关于C结构体bit field的跨平台的教训
C语言的STRUCT提供了一种叫bit field的语法,可以根据需要决定成员占用某字节的从X位到Y位,例如,下面一个结构:struct tagtest
{
char a:4;
char b:2;
char c:2;
};
这个定义的含义是整个结构是一个字节长度,成员a占4位,b占2位,c占2位。这样定义以后,我们可以方便的通过设置成员的值来设置结构,而不需要进行位操作了。例如:
tagtest myTest;
myTest.a = 10;
myTest.b = 2;
myTest.c = 1;
但今天发现一个问题,就是windows系统上的和MAC上对待这个结构是不同的;现象如下:
如果在windows上这是上面的值,在MAC上得到的结构成员值为:
myTest.a = 6;myTest.b = 2;myTest.c = 2;
仔细分析之后觉得这个不是字节序的问题,因为字节序对一个字节是不起作用的,如果起作用那传输数据就麻烦了了;那么是什么问题导致的呢?
应该是编译器造成的,规律如下:
在WINDOS上,编译器认为c是字节的高位,而a是字节的低位;但MAC上正好相反了;a 是字节的低位,c是字节的低位。
紧记在心!!! 最好还是使用与或的位操作比较安全。 ADS中貌似不能这样操作...? ADS支持bit field的语法 本帖最后由 ruiwei0201 于 2009-8-25 16:21 编辑
回LS: 下面是我测试代码:
typedef union _tagTEST{
struct{
unsigned char bLOW4 : 4;
unsigned char bHigh4 : 4;
}stTest;
unsigned char bTest;
}unTEST;
unTEST unTest;
unsigned char i;
unTest.stTest.bLow4 = 0x0F;
stTest.stTest.bHigh4 = 0x06;
i = unTest.bTest;
我在ADS中编译后最后一条语句没有编译结果(无反汇编语句),请帮忙解释一下好不? unTEST unTest;
unsigned char i;
unTest.stTest.bLOW4 = 0x0F;
unTest.stTest.bHigh4 = 0x06;
i = unTest.bTest;
改成以上看看. 你书写有错误无法编译通过 我书写错误是我手动往这里敲的,编译肯定是不会报错的。。。我已经能调试了,你想编译会有错误吗 同意2楼的说法,最好还是使用与或的位操作比较安全 bit field顺序和endian有关; 对齐方式决定的,比较古老的问题了 看了一楼的东东,觉得奇怪。位域是和endian有关,但是不明白的是,你在window下如下操作
myTest.a = 10;
myTest.b = 2;
myTest.c = 1;
然后再读出来它得值应该还是10,2,1,
你在MAC下如下操作
myTest.a = 10;
myTest.b = 2;
myTest.c = 1;
然后再读出来它得值应该还是10,2,1,
我不明白你的意思,你在误导大家。我觉得不管在什么编译器环境。你对位域变量赋值后,再读位域变量的值,应该是不变得在A编译器上是多少,在B编译器上还是多少 1. 注意对齐问题. ADS下如:
typedef __packed struct
{
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short wTotalLength;
unsigned char bNumInterfaces;
unsigned char bConfigurationValue;
unsigned char iConfiguration;
unsigned char bmAttributes;
unsigned char MaxPower;
} USB_config_desc_t;
2. ADS下的位结构肯定没问题. 俺用过N遍. N>10.
3. 不同的编译器. 同样的数据结构出来的结果有可能不一样.
页:
[1]