获取字中字节地址的最安全的跨平台方法是什么?
What is the safest cross-platform way to get the address of a byte in a word?
以下将 byte
在大端上设置为 1,在小端上设置为 0。
uint16_t word = 0x0001;
uint8_t byte = *(((uint8_t *)&word) + 1);
有什么方法可以跨平台安全地获取低字节或高字节的地址吗?
可能是这样的:
int isBigEndian()
{
uint16_t word = 0x0001;
return *(((uint8_t *)&word) + 1);
}
void main()
{
uint16_t word = 0x0001;
uint8_t byte = *(((uint8_t *)&word) + isBigEndian());
printf("%d\n", byte);
}
为避免每次都在 运行 检查,您可以使用 #define
并使用 assert
验证它是否正确。像这样:
#define BIG_ENDIAN 0 // 0 or 1 depending on what the platform is
void main()
{
assert(isBigEndian() == BIG_ENDIAN); // Make sure #define is OK
// more code...
}
在代码的其他地方,您使用符号 BIG_ENDIAN
来根据平台编译代码。所以除了 assert
.
没有其他实际检查
从 C99 开始,代码可以使用 复合文字 来查找 MSByte 地址偏移量。
让编译器形成高效的代码。
下面使用一个 4 字节的示例来帮助说明 big、little 和 PDP endian 的遵守情况。
int main() {
uint32_t word = 0x12345678;
printf("%p\n", (void*)&word);
for (unsigned i=0; i<sizeof word; i++) printf("%x\n", ((uint8_t*) &word)[i]);
uint8_t *msbyte_address = ((uint8_t*) &word) + //
// v----------------------------------------------------v compound literal
( union { uint32_t u32; uint8_t u8[4]; }) {0x00010203}.u8[0];
// value at 1st byte ^---^
printf("%p\n", (void*)msbyte_address);
}
示例输出(小端)
0xffffcbfc
78
56
34
12
0xffffcbff
对于uint16_t
uint16_t word = 0x1234;
uint8_t *msbyte_address = ((uint8_t*) &word) +
( union { uint16_t u16; uint8_t u8[2]; }) {0x0001}.u8[0];
以下将 byte
在大端上设置为 1,在小端上设置为 0。
uint16_t word = 0x0001;
uint8_t byte = *(((uint8_t *)&word) + 1);
有什么方法可以跨平台安全地获取低字节或高字节的地址吗?
可能是这样的:
int isBigEndian()
{
uint16_t word = 0x0001;
return *(((uint8_t *)&word) + 1);
}
void main()
{
uint16_t word = 0x0001;
uint8_t byte = *(((uint8_t *)&word) + isBigEndian());
printf("%d\n", byte);
}
为避免每次都在 运行 检查,您可以使用 #define
并使用 assert
验证它是否正确。像这样:
#define BIG_ENDIAN 0 // 0 or 1 depending on what the platform is
void main()
{
assert(isBigEndian() == BIG_ENDIAN); // Make sure #define is OK
// more code...
}
在代码的其他地方,您使用符号 BIG_ENDIAN
来根据平台编译代码。所以除了 assert
.
从 C99 开始,代码可以使用 复合文字 来查找 MSByte 地址偏移量。
让编译器形成高效的代码。
下面使用一个 4 字节的示例来帮助说明 big、little 和 PDP endian 的遵守情况。
int main() {
uint32_t word = 0x12345678;
printf("%p\n", (void*)&word);
for (unsigned i=0; i<sizeof word; i++) printf("%x\n", ((uint8_t*) &word)[i]);
uint8_t *msbyte_address = ((uint8_t*) &word) + //
// v----------------------------------------------------v compound literal
( union { uint32_t u32; uint8_t u8[4]; }) {0x00010203}.u8[0];
// value at 1st byte ^---^
printf("%p\n", (void*)msbyte_address);
}
示例输出(小端)
0xffffcbfc
78
56
34
12
0xffffcbff
对于uint16_t
uint16_t word = 0x1234;
uint8_t *msbyte_address = ((uint8_t*) &word) +
( union { uint16_t u16; uint8_t u8[2]; }) {0x0001}.u8[0];