Ale*_*ros 11 c standards integer-overflow c99
对于C(short,int,long等)中的"标准"有符号整数类型的所有操作,如果它们产生超出[TYPE_MIN,TYPE_MAX]间隔的结果(其中TYPE_MIN,TYPE_MAX是最小值和最大整数值),则表现出未定义的行为可以通过特定整数类型存储的.
但是,根据C99标准,所有intN_t类型都需要具有二进制补码表示:
7.8.11.1精确宽度整数类型
1. typedef名称intN_t指定有符号整数类型,其宽度为N,无填充位和二进制补码表示.因此,int8_t表示具有正好8位宽度的有符号整数类型.
这是否意味着intN_tC99 中的类型在整数溢出的情况下表现出良好定义的行为?例如,这段代码定义明确吗?
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
printf("Minimum 32-bit representable number: %" PRId32 "\n", INT32_MAX + 1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Kei*_*son 12
不,它没有.
对类型范围内的值的二进制补码表示的要求并不意味着溢出行为的任何内容.
类型<stdint.h>只是现有类型的typedef(别名).添加typedef不会更改类型的行为.
C标准第6.5节第5段(C99和C11)仍然适用:
如果在计算表达式期间发生异常情况(即,如果结果未在数学上定义或未在其类型的可表示值范围内),则行为未定义.
这不会影响无符号类型,因为无符号运算不会溢出; 它们被定义为产生包装结果,减少模数TYPE _MAX + 1.除了无符号类型比int提升到(带符号)更窄int,因此可能遇到相同的问题.例如,这个:
unsigned short x = USHRT_MAX;
unsigned short y = USHRT_MAX;
unsigned short z = x * y;
Run Code Online (Sandbox Code Playgroud)
如果short比较窄,会导致未定义的行为int.(如果short和int分别是16位和32位,则65535 * 65535产生4294836225,超过INT_MAX.)