__int128@min负值的UDL(用户定义的文字)整数溢出
Integer overflow with UDL (user defined literal) for __int128 @ min negative value
为了清晰和简单起见,我将缩短以下数字如下:
−170,141,183,460,469,231,731,687,303,715,884,105,728
作为-170…728
170,141,183,460,469,231,731,687,303,715,884,105,727
作为170…727
这些数字表示128位有符号整数(gcc
中的__int128(的最小值和最大值。
我为这种数据类型实现了用户定义的文字(原始文字(,因为gcc没有提供定义这种类型的常量的方法:_u128
用于unsigned __int128
,_i128
用于__int128
。
减号字符不是UDL的一部分,而是应用于UDL结果的一元减号运算符。
因此,对于-ddddd_i128
(其中d
是一个数字(,UDL计算一个具有正值ddddd
的有符号__int128
,然后编译器将对其应用一元减号运算符。到目前为止,一切都很好。
问题出在-170…128_i128
(它应该是__int128
的有效值(上:
UDL计算刚好在__int128
范围之外的有符号__int128
正数170…128
,从而导致未定义行为(有符号整数溢出(。
有什么解决方案可以用UDL表示这个数字常数吗?
我的UDL是声明的(目前只是一个非常常量表达式,loopy版本((它们是原始文字(:
unsigned __int128 operator"" _u128(char const *str);
__int128 operator"" _i128(char const *str);
一些用法:
1000000000000000000000000000000000_i128
-1000000000000000000000000000000000_i128
-170141183460469231731687303715884105728_i128 // <-- this has UB
170141183460469231731687303715884105727_u128
340282366920938463463374607431768211455_u128
我知道有多种方法可以定义常数-170…728
,比如移位、数学运算,但我希望能够以一致的方式创建它,例如,我不希望出现这种情况:你可以使用这个UDL创建任何常数,除了-170…728_i128
,你必须使用额外的技巧。
这本质上与实现者在实现<limits.h>
时遇到的问题相同:INT_MIN
(在典型的32位系统上(不能定义为-2147483648
。它可以(通常(定义为(-2147483647 - 1)
。你必须做一些类似的事情。可能没有任何方法可以用一个否定运算符和文字来表示最负的数字,但这没关系:根本不需要它。
- 'short int'持有的值溢出,但"自动"不会溢出?
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 大于65535的C++数组[size]引发不一致的溢出
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- C++中无符号字符溢出
- 如何使用字符串文字作为宏参数
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 构造<int>具有 2 个字符串文字的向量
- 将数字打印成文字
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 方便地对C++中的所有字符串文字进行模糊处理
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 整数溢出,最大值为 pow(10,19)
- 获取隐式转换溢出从无符号到已签名的警告
- 使用 strcat 获取缓冲区溢出错误
- LeetCode 1:两和 - 地址清理器:堆缓冲区溢出地址
- __int128@min负值的UDL(用户定义的文字)整数溢出