[英]C Casting from pointer to uint32_t to a pointer to a union containing uint32_t
我想知道是否将指向uint32_t的指针转换为包含uint32_t的并集的指针会导致C中定义的行为,即
typedef union
{
uint8_t u8[4];
uint32_t u32;
} T32;
void change_value(T32 *t32)
{
t32->u32 = 5678;
}
int main()
{
uint32_t value = 1234;
change_value((T32 *)&value); // value is 5678 afterwards
return EXIT_SUCCESS;
}
这是有效的C吗? 提前谢谢了。
您问题的一般答案是,不,这通常没有定义。 如果联合包含比uint32_t
具有更大对齐方式的字段,则此类联合必须具有最大对齐方式,然后访问该指针将导致UB。 例如,如果在示例中将uint8_t
替换为double
则可能会发生这种情况。
但是,在您的特定情况下,行为已得到明确定义。 uint8_t
(如果存在)很可能就是unsigned char
并且所有字符类型始终具有最少的对齐要求。
编辑:正如R ..在他的评论中提到的那样,您的方法还有其他问题。 首先,从理论上讲,如果存在该宽度的无符号“扩展整数类型”,则uint8_t
可能与unsigned char
不同。 这是非常不可能的,我从未听说过这样的架构。 其次,您的方法会遇到混叠问题,因此您应格外小心。
冒着产生否决票的风险...从概念上讲,您尝试执行的操作没有任何问题。 也就是说,定义一个存储区,可以将其视为一个32位整数的四个字节,然后使用指针引用和修改该存储区。
但是,我想问一问为什么要在意图模糊的地方编写代码。 您真正要做的是迫使下一个阅读您的代码的程序员思考几分钟,甚至尝试一些测试程序。 因此,这种编程风格是“昂贵的”。
您可以像这样轻松定义值:
T32 value;
// etc.
change_value(&value);
然后避免施法和后续焦虑。
由于保证所有的工会成员都从相同的内存地址开始,因此编写的程序不会导致未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.