在CI中,可以看到许多代码为size_t变量添加或赋予整数文字.
size_t foo = 1;
foo += 1;
Run Code Online (Sandbox Code Playgroud)
这里发生了什么转换,是否会发生a size_t被"升级"为a int然后转换回size_t?如果我在最大程度,那还会环绕吗?
size_t foo = SIZE_MAX;
foo += 1;
Run Code Online (Sandbox Code Playgroud)
这是定义的行为吗?它是一个无符号类型size_t,它int添加了一个符号(可能是一个更大的类型?)并转换回一个size_t.有签名整数溢出的风险吗?
写一些foo + bar + (size_t)1代替的东西是否有意义foo + bar + 1?我从来没有看到这样的代码,但我想知道整数促销是否有必要是否有必要.
C89没有说明size_t将如何排名或者究竟是什么:
结果的值是实现定义的,其类型(无符号整数类型)是在头中定义的size_t.
当前的C标准允许在执行以下代码时可能导致未定义行为的实现,但是这样的实现不存在,并且可能永远不会:
size_t foo = SIZE_MAX;
foo += 1;
Run Code Online (Sandbox Code Playgroud)
类型size_t为无符号类型1,最小范围为:2 [0,65535].
类型size_t可以定义为unsigned short类型的同义词.无符号短类型可以定义为具有16个精度位,范围为:[0,65535].在这种情况下,SIZE_MAX的值为65535.
int类型可以定义为具有16个精度位(加一个符号位),二进制补码表示,范围:[ - 65536,65535].
表达式foo + = 1,相当于foo = foo + 1(除了foo只计算一次,但这里没有关系).变量foo将使用整数提升3进行提升.它将被提升为int类型,因为int类型可以表示size_t类型的所有值和size_t的等级,是unsigned short的同义词,低于int的等级.由于size_t和int的最大值相同,因此计算会导致签名溢出,从而导致未定义的行为.
这适用于当前的标准,它也应该适用于C89,因为它对类型没有更严格的限制.
避免任何可以想象的实现的带符号溢出的解决方案是使用无符号整数常量:
foo += 1u;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果foo的排名低于int,则使用通常的算术转换将其提升为unsigned int.
1(引自ISO/IEC 9899/201x 7.19通用定义2)
size_t
是sizeof运算符结果的无符号整数类型;
2(引自ISO/IEC 9899/201x 7.20.3其他整数类型的
限制2)size_t限制
SIZE_MAX 65535
3(引自ISO/IEC 9899/201x 6.3.1.1布尔,字符和整数2)
如果可以使用int或unsigned int,则可以在
表达式中使用以下内容:具有整数类型的对象或表达式(除了int或unsigned int)其整数转换等级小于或等于int和unsigned int的等级.
如果int可以表示原始类型的所有值(由宽度限制,对于位字段),则该值将转换为int; 否则,它将转换为unsigned int.这些被称为整数促销.整数促销不会更改所有其他类型.
| 归档时间: |
|
| 查看次数: |
2251 次 |
| 最近记录: |