clang enum溢出

Dav*_*eri 5 c enums overflow

使用-Wall -pedantic

#include <limits.h>
#include <stdio.h>

int main(void)
{
    enum x {
        a,
        max = INT_MAX,
        out_1
    };
    enum y {
        b,
        out_2 = INT_MAX + 1
    };


    printf("%d %d\n", out_1, out_2);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

铿锵回归

demo.c:9:3: warning: overflow in enumeration value
                out_1
                ^
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,编译器没有警告out_2溢出,他的值在编译时是未知的?

tep*_*pic 3

在第一种情况下,编译器本身会尝试选择一个导致溢出的整数,因此会警告您。它很可能会产生INT_MIN. 该标准允许 a 中的任何值signed int都是枚举常量(见底部)。

\n\n

在第二个中,表达式(INT_MAX + 1)在分配给 之前进行计算out_2。此处表达式中的溢出会产生允许的结果,但这是未定义的行为。然后,有效结果存储在枚举中,这就是不会产生第一个错误的原因。

\n\n

clang (3.2) 也不会对此发出警告,这实际上是相同的:

\n\n
int a = INT_MAX + 1;\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这方面,clang 的行为不符合 C 标准,因为这是未定义的。

\n\n

相比之下,gcc 的输出使差异完全清晰:

\n\n
In function \xe2\x80\x98main\xe2\x80\x99:\n9:9: error: overflow in enumeration values\n13:25: warning: integer overflow in expression [-Woverflow]\n
Run Code Online (Sandbox Code Playgroud)\n\n

Intel 编译器会忽略枚举溢出,但会警告整数溢出:

\n\n
enum.c(13): warning #61: integer operation result is out of range\n      out_2 = INT_MAX + 1\n                      ^\n
Run Code Online (Sandbox Code Playgroud)\n\n


\n作为参考,来自 C99 标准 6.7.7.2.2,“定义枚举常量值的表达式应为整数常量表达式,其值可表示为int; .3”,枚举器列表中的 identi\xef\xac\x81ers 被声明为具有类型的常量int,并且可以出现在允许的任何位置。”即枚举常量可以是任何int值,并且具有int类型。定义的枚举变量的结果类型可以be char,int或unsigned int, 只要它允许枚举中所有可能的常量。因此enums示例中的两个都是未定义的,因为它们都需要整数溢出。第一个明显是非法的。

\n