当询问C中常见的未定义行为时,灵魂比我提到的严格别名规则更加开明.
他们在说什么?
我一直在寻找,但找不到明确的答案.
很多人说使用工会来打字 - 双关语是不明确的和不好的做法.为什么是这样?考虑到你写入原始信息的内存并不仅仅是自己的改变,我看不出为什么它会做任何未定义的任何原因(除非它超出了堆栈的范围,但这不是一个联合问题,这将是糟糕的设计).
人们引用严格的别名规则,但在我看来,就像说你不能这样做,因为你做不到.
如果不打双关语,联盟的意义又是什么呢?我在某个地方看到它们应该被用来在不同的时间使用相同的内存位置来获取不同的信息,但为什么不在再次使用之前删除信息呢?
总结一下:
额外信息:我主要使用的是C++,但想了解它和C.特别是我正在使用工会在浮点数和原始十六进制之间进行转换以通过CAN总线发送.
cppreference †声明:
具有普通默认构造函数的对象可以通过
reinterpret_cast在任何适当对齐的存储上使用来创建,例如在分配有的存储器上std::malloc.
这意味着以下是明确定义的代码:
struct X { int x; };
alignas(X) char buffer[sizeof(X)]; // (A)
reinterpret_cast<X*>(buffer)->x = 42; // (B)
Run Code Online (Sandbox Code Playgroud)
以下是三个问题:
X开始的生命周期是什么时候?如果在线(B),它是否被视为获取存储?如果在线(A),如果有一个分支(A)和(B)有条件地构建一个X或其他一些pod,Y怎么办?†请注意,这是一个旧链接.针对这个问题,措辞发生了变化.它现在写道:
但是,与C不同,通过简单地重新解释适当对齐的存储来创建具有普通默认构造函数的对象,例如分配的内存
std::malloc:placement-new是正式引入新对象并避免潜在的未定义行为所必需的.