gpt4 book ai didi

指向 struct 的指针可以别名为 unsigned char 数组吗?

转载 作者:行者123 更新时间:2023-11-30 16:59:56 25 4
gpt4 key购买 nike

#include "stdio.h"  


/* array to store data receeived from CAN Bus */
unsigned char a[8] = {0xCD, 0xEF, 0x12, 0x34, 0x50, 0x00, 0x00, 0x00};

typedef struct {
unsigned int a:12;
unsigned int b:12;
unsigned int c:12;
unsigned int unused:28;
}test;

test *tptr;

int main(void)
{

tptr = (test*)( (void*)&a); // is this line braking any aliasing rule

if(tptr->a == 0xCDE)
{
printf("\n data received ok");

}

return 0;
}

我最近了解到 C 中由于指针别名导致的问题。我想知道上面的代码是否违反了任何规则。这会导致问题吗?

我知道位域的顺序取决于机器和实现。然而,我的问题是关于指针别名规则,我想更清楚地理解

最佳答案

它确实打破了严格的别名。一些(理智的)编译器确实推断出显然应该允许 tptra 别名,但是标准并不能保证这一点。事实上,GCC 不会将 tptr 视为 a 的别名。

另一个问题是a的对齐。 x86 在这方面具有相当的宽容度,但许多其他架构(包括 ARM)则不然。

在仅支持从地址获取 int 的架构上考虑 (int)&a == 0xFFF02sizeof(int) == 4它们本身就是 sizeof(int) 的倍数。这样的unaligned access如果您执行 *(int*)&a ,或者更糟糕的是程序访问错误的位置,则会导致总线错误。

为了避免未定义的行为,请记住,保证可以在没有对齐或别名约束的情况下通过 unsigned char* 进行访问,而不是相反。因此使用:

test buf;
can_recv((unsigned char*)&buf, sizeof buf);
if(tptr->a == 0xCDE)
{
printf("\n data received ok");

}

另一个可移植性问题是您希望以某种方式打包位字段。 The standard doesn't guarantee that however 。如果您想要可移植的行为,请将自己限制在位字段接口(interface) (bitfield.b1 = 1) 中,并且不要通过其他方式修改 bitfied。

如果可移植性不是问题,请确保设置适当的编译器标志来保证您期望的位字段打包。

关于指向 struct 的指针可以别名为 unsigned char 数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37901052/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com