不同编译器中C ++和C之间无符号位域整数表达式的截断不一致
编辑2: 当以前驻留在C ++源文件中但完全移入C文件的函数开始返回不正确的结果时,我正在调试一个奇怪的测试失败。下面的MVE允许重现GCC问题。但是,当我一时兴起,用Clang(后来又用VS)编译示例时,得到了不同的结果!我无法弄清楚是将其视为编译器之一中的错误,还是C或C ++标准允许的未定义结果的体现。奇怪的是,没有一个编译器给我有关该表达式的任何警告。 罪魁祸首是这样的表达: ctl.b.p52 << 12; 在这里,p52键入为uint64_t;它也是工会的一部分(见control_t下文)。移位操作不会丢失任何数据,因为结果仍然适合64位。但是,如果我使用C编译器,那么GCC决定将结果截断为52位!使用C ++编译器,将保留所有64位结果。 为了说明这一点,下面的示例程序用相同的主体编译了两个函数,然后比较了它们的结果。c_behavior()放在C源文件和cpp_behavior()C ++文件中,并main()进行比较。 带有示例代码的存储库:https : //github.com/grigory-rechistov/c-cpp-bitfields 标头common.h定义64位宽位域和整数的并集,并声明两个函数: #ifndef COMMON_H #define COMMON_H #include <stdint.h> typedef union control { uint64_t q; struct { uint64_t a: 1; uint64_t b: 1; uint64_t c: 1; uint64_t d: 1; uint64_t e: 1; uint64_t f: 1; uint64_t g: …