WeHack BBS
C/C++的short类型加法溢出是否是未定义行为? - 可打印的版本

+- WeHack BBS (https://bbs.wehack.space)
+-- 版块: 计算机技术 (https://bbs.wehack.space/forum-5.html)
+--- 版块: 程序设计讨论区 (https://bbs.wehack.space/forum-14.html)
+--- 主题: C/C++的short类型加法溢出是否是未定义行为? (/thread-300.html)



C/C++的short类型加法溢出是否是未定义行为? - vimacs - 09-25-2021

GCC邮件列表中有人提到一个测试例子:https://gcc.gnu.org/pipermail/gcc/2021-September/237411.html

代码:
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 加法溢出的未定义行为。