【发布时间】:2019-05-28 14:13:08
【问题描述】:
我已经定义了一个枚举类型的位域来匹配嵌入式系统中的一组位。我正在尝试在 MSVC 中为代码编写测试工具,但比较应该相等的值失败了。
定义如下:
typedef enum { SERIAL, PARALLEL } MODE_e;
typedef union {
struct {
TYPE_e Type : 1; // 1
POSITION_e 1Pos : 1; // 2
POSITION_e 2Pos : 1; // 3
bool Enable : 1; // 4
NET_e Net : 1; // 5
TYPE_e Type : 1; // 6
bool En : 1; // 7
TIME_e Time : 3; // 8-10
MODE_e Mode : 1; // 11
bool TestEn : 1; // 12
bool DelayEn : 1; // 13
MODE_e Mode : 1; // 14
bool xEn : 1; // 15
MODE_e yMode : 1; // 16
bool zEnable : 1; // 17
} Bits;
uint32_t Word;
} BITS_t;
后来以下比较失败:
Store.Bits.Mode = PARALLEL;
if (store.Bits.Mode == PARALLEL)
...
我在调试器中检查了Mode 布尔值,它看起来很奇怪。 Mode 的值为-1。
就好像 MSVC 认为该值是 2 的补码,但 1 位宽,所以 0b1 是十进制的 -1。枚举将PARALLEL 设置为1,因此两者不匹配。
比较在使用 LLVM 或 GCC 的嵌入式端可以正常工作。
哪种行为是正确的?我认为 GCC 和 LLVM 在位域等领域对 C 标准的支持比 MSVC 更好。更重要的是,我能否在不对嵌入式代码进行重大更改的情况下解决这种差异?
【问题讨论】:
-
位域是不可移植的,因此推测标准合规性没有多大意义。
-
@Lundin 是的,你是对的。嗯,那我可能会被搞砸……或者我可以使用一些预处理程序来处理它。
-
@Lundin 或者更重要的是,用于枚举的整数类型是实现定义的。
-
@dbush 当然,我在问是否有办法让它同时适用于 LLVM 和 MSVC。我能想到的最好的方法是#ifdef _WIN32
-
@dbush 也许是冰山一角:) 这里有多个问题,枚举只是其中之一。我写了一个详细的答案,列出了我能发现的所有可移植性问题。
标签: c visual-c++ bit-fields