c++ - 枚举常量在 C 和 C++ 中的行为不同

标签 c++ c

为什么会这样:

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

int main() {
    enum en_e {
        en_e_foo,
        en_e_bar = UINT64_MAX,
    };
    enum en_e e = en_e_foo;
    printf("%zu\n", sizeof en_e_foo);
    printf("%zu\n", sizeof en_e_bar);
    printf("%zu\n", sizeof e);
}

在 C 中打印 4 8 8 和在 C++ 中打印 8 8 8(在具有 4 字节整数的平台上)?

我的印象是 UINT64_MAX 赋值会强制所有枚举常量至少为 64 位,但 en_e_foo 在普通 C 中保持为 32。

差异的原因是什么?

最佳答案

在 C 中,enum 常量的类型为 int。在 C++ 中,它是枚举类型。

enum en_e{
    en_e_foo,
    en_e_bar=UINT64_MAX,
};

在 C 中,这是一个违反约束,需要诊断(if UINT64_MAX 超过 INT_MAX,即它很可能确实如此)。 C 编译器可能会完全拒绝该程序,或者它可能会打印一个警告,然后生成一个行为未定义的可执行文件。 (不是 100% 清楚违反约束的程序必然具有未定义的行为,但在这种情况下,标准并没有说明行为是什么,所以这仍然是未定义的行为。)

gcc 6.2 不会对此发出警告。 clang 。这是 gcc 中的一个错误;当使用标准头文件中的宏时,它会错误地禁止某些诊断消息。感谢 Grzegorz Szpetkowski 找到错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71613

在 C++ 中,每个枚举类型都有一个基础类型,它是某种整数类型(不一定是 int)。此基础类型必须能够表示所有常量值。所以在这种情况下,en_e_fooen_e_bar 都是 en_e 类型,它必须至少为 64 位宽,即使 int 更窄。

关于c++ - 枚举常量在 C 和 C++ 中的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41836658/

相关文章:

c - 我无法理解第二个 printf 打印的内容

c - printf 修改字符串

c - 为什么 printf 打印不正确的值?

编译器报告 "Segmentation fault: 11"

c++ - 更改选项卡颜色中的静态背景 C++

c++ - 在我自己的开源项目中使用经过修改的 C++ 头文件库的通常方法是什么?

c++ - 来自 openCV 的 imread 使图像变暗

c++ - 了解成员初始值设定项列表

c++ - 复制包含字符串的 CORBA::Any 时 CORBA 程序段错误

c - 单核处理双核并行编程