c++ - “整数常量太大以至于它是无符号的”编译器警告理由
问题描述
以下 C/C++ 代码:
long long foo = -9223372036854775808LL; // -2^63
编译 (g++) 并带有警告
整数常量太大以至于它是无符号的。
clang++ 给出了类似的警告。
感谢这个错误报告:https ://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661 。我现在明白为什么 GCC 会给出这个警告。不幸的是,对错误报告的响应并没有很好地解释这种行为的原因。
问题:
- 为什么 32/16/8 位有符号整数常量的等效代码没有给出警告?
- GCC 和 Clang 都给出了这个警告,所以这显然是故意的行为,而不是像在响应错误报告时所建议的那样“使其更容易解析”。为什么?
- 这种行为是 C/C++ 标准规定的吗?其他一些标准?
解决方案
这与如何定义整数常量的类型有关。
首先,正如 gcc 错误报告中提到的,-9223372036854775808LL
实际上是两个标记:一元运算-
符和整数常量9223372036854775808LL
。所以警告只适用于后者。
C 标准的第 6.4.4.1p5 节规定:
整数常量的类型是可以表示其值的对应列表中的第一个。
基于此,没有后缀的十进制整数常量将具有类型int
, long
, 或long long
基于值。这些都是有符号的类型。因此,任何小到适合 8 位或 16 位类型的值仍然具有 type int
,而对于 32 位有符号 int 而言太大的值将具有 typelong
或long long
取决于该系统上类型的大小。带有LL
后缀的常量也是如此,但只long long
尝试了类型。
出现警告是因为您使用的值不适合上述类型列表。任何较小的值都将导致该值具有有符号类型,这意味着没有转换为无符号。
推荐阅读
- python - 将字符串添加到 python 列表的每个元素
- octopus-deploy - 使用 Octopus 中的变量集刷新所有项目的变量
- ajax - 相同的域和协议,但“被 CORS 策略阻止:不存在‘Access-Control-Allow-Origin’”
- firebase - 在阅读列表之间通过 Dialogflow-fulfillment 请求许可
- python - 对字符串变量的实时语音
- android - 内置 apk 导致白屏和标题
- bitbucket - 如何在 intelliJ 中查看 git 拉取请求(托管在 bitbucket 上)?
- html - 相当于什么
- python - 如何从带有数字的字符串中去除字母,以便将其更改为 int 并排序
- javascript - 如何在 react-native 中全局监听冒泡事件?