c - 为什么 C 编译器在为有符号类型分配过高的整数值时不发出警告?
问题描述
(假设是 64 位机器)
例如
int n = 0xFFFFFFFF; //max 32bit unsigned number
printf("%u\n", n);
常规有符号整数(32 位)可以存储的最大正数是0x7FFFFFFF
.
在上面的示例中,我将最大无符号整数值分配给常规有符号整数,我没有收到来自 GCC 的警告或错误,并且打印结果没有问题(带有-Wall -Wextra
)。
U
将或附加L
到十六进制常量不会改变任何内容。
这是为什么?
解决方案
0xFFFFFFFF
,在unsigned
最大值为 2 32 -1 的平台上,将具有unsigned
根据标准的“6.4.4.1 整数常量”的类型。
然后我们进行转换:
6.3.1.3 有符号和无符号整数
1 当整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新的类型表示,则不变。
2 否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上反复加减一来转换该值,直到该值在新类型的范围内。60)
3 否则,新类型是有符号的,值不能在其中表示;结果要么是实现定义的,要么是产生实现定义的信号。
因此,结果是实现定义的或引发实现定义的信号。
现在,您使用 format 打印您int
的格式%u
,这完全不匹配。虽然这严格来说是 UB,但假设您有 2s-complement 并且原始分配使用环绕,您可能会得到原始常量。
推荐阅读
- option - AMP:选择选项并更改另一个元素中的选项
- mysql - 使用 sequelize 事务记录对象数组
- c++ - 如何在地图中搜索本身是一对的键?
- grails - 如何将我从 findAllBy 获得的值插入到地图中?
- apache-nifi - NiFi读取和修改文件内容
- sql-server - SQL Server如何避免WHERE子句中的时区转换
- java - 当项目存储在 Arr[0] 中时,如何确定项目是否存在于大小为 2 的数组的哈希集中?
- node.js - AWS Lambda 与外部 REDIS 实例的连接不起作用
- angular - 无法将组件导入页面 - Ionic 4
- ruby-on-rails - hexapdf 页面方向和内容顺序