09-25-2021, 09:39 AM
GCC邮件列表中有人提到一个测试例子:https://gcc.gnu.org/pipermail/gcc/2021-September/237411.html
这里的问题在于变量 c 最后会溢出,即 SHORT_MAX+1==SHORT_MIN. 那么这个行为是否为未定义行为?
这里就要说到C语言的integer promotion的问题,C语言会对操作数进行类型提升,这是一种隐式转换。类型提升规则如下。
就是说 short 会先转为 int,然后做 int 的加法,最后再截断为 short,这些都是已定义的行为。那么如果 int 是 32 位,short 是 16 位,那么 SHORT_MAX+1=SHORT_MIN 是已定义的。
如果 int 和 short 长度相等,那么就会出现 int 加法溢出的未定义行为。
代码:
int a, b;
short c;
int
main ()
{
int j, d = 1;
for (; c >= 0; c++)
{
BODY:
a = d;
d = 0;
if (b)
{
xprintf (0);
if (j)
xprintf (0);
}
}
xprintf (d);
exit (0);
}
这里的问题在于变量 c 最后会溢出,即 SHORT_MAX+1==SHORT_MIN. 那么这个行为是否为未定义行为?
这里就要说到C语言的integer promotion的问题,C语言会对操作数进行类型提升,这是一种隐式转换。类型提升规则如下。
引用:If an int can represent all values of the original type (as restricted by the width, for a bit-field), the
value is converted to an int; otherwise, it is converted to an unsigned int. These are called the
integer promotions. All other types are unchanged by the integer promotions.
就是说 short 会先转为 int,然后做 int 的加法,最后再截断为 short,这些都是已定义的行为。那么如果 int 是 32 位,short 是 16 位,那么 SHORT_MAX+1=SHORT_MIN 是已定义的。
如果 int 和 short 长度相等,那么就会出现 int 加法溢出的未定义行为。