假设我有以下C代码.
unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;
Run Code Online (Sandbox Code Playgroud)
什么隐式转换在这里怎么回事,这是代码为安全的所有值u和i?(安全,从某种意义上说,即使此示例中的结果会溢出到某个巨大的正数,我也可以将其转换回int并获得真实的结果.)
编辑2:
当以前驻留在 C++ 源文件中但逐字移入 C 文件的函数开始返回不正确的结果时,我正在调试一个奇怪的测试失败。下面的 MVE 允许重现 GCC 的问题。然而,当我一时兴起用 Clang(后来用 VS)编译这个例子时,我得到了不同的结果!我不知道是将其视为其中一个编译器中的错误,还是将其视为 C 或 C++ 标准允许的未定义结果的表现。奇怪的是,没有一个编译器给我任何关于表达式的警告。
罪魁祸首是这个表达式:
ctl.b.p52 << 12;
Run Code Online (Sandbox Code Playgroud)
在这里,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 …Run Code Online (Sandbox Code Playgroud)