此代码未按我的预期返回,标识符应为 0xABC 是否可以解决此问题?
#include <stdio.h>
#include "stdint.h"
typedef struct {
union {
struct {
uint8_t address: 8;
uint16_t identifier: 16;
};
uint32_t fullAddress;
};
} isotpAddress_t;
int main() {
isotpAddress_t myAddress;
myAddress.fullAddress = 0xABCDE;
printf("Address: 0x%02X\n", myAddress.address); // Output: Address: 0xDE
printf("Identifier: 0x%04X\n", myAddress.identifier); // Output: Identifier: 0x000A but want 0x0ABC
return 0;
}
输出:
> Address: 0xDE
> Identifier: 0x000A
结构中位域的布局很大程度上是由实现定义的。话虽这么说,这就是可能发生的事情。
struct {
uint8_t address: 8;
uint16_t identifier: 16;
};
实现通常会使用位域的基本类型作为一个或多个位域的存储单元。如果两个位域的基本类型相同并且有足够的空间,那么它们通常会被放入同一个存储单元中。
在上面的情况下,第一个位字段用尽了它所包含的整个
uint8_t
存储单元。下一个位字段位于 uint16_t
存储单元中,因此在它之前可能有 1 个字节的填充以进行正确对齐。这就是你的“丢失”字节所在的位置。
如果将位域的基本类型更改为
uint32_t
,则两者很可能位于同一存储单元中,并且它们之间没有填充。
struct {
uint32_t address: 8;
uint32_t identifier: 16;
};
通过此更改,在 CentOS 7 上使用 gcc 4.8.5 进行编译,我能够得到您想要的结果。但同样,这个结果是由实现定义的。不能保证这适用于所有实现。