对于许多问题,答案似乎可以在"标准"中找到.但是,我们在哪里找到它?最好是在线.
谷歌搜索有时会觉得徒劳,尤其是对于C标准,因为他们在编程论坛的大量讨论中被淹没.
要开始这个,因为这些是我现在正在搜索的,那里有很好的在线资源:
我一直在寻找,但找不到明确的答案.
很多人说使用工会来打字 - 双关语是不明确的和不好的做法.为什么是这样?考虑到你写入原始信息的内存并不仅仅是自己的改变,我看不出为什么它会做任何未定义的任何原因(除非它超出了堆栈的范围,但这不是一个联合问题,这将是糟糕的设计).
人们引用严格的别名规则,但在我看来,就像说你不能这样做,因为你做不到.
如果不打双关语,联盟的意义又是什么呢?我在某个地方看到它们应该被用来在不同的时间使用相同的内存位置来获取不同的信息,但为什么不在再次使用之前删除信息呢?
总结一下:
额外信息:我主要使用的是C++,但想了解它和C.特别是我正在使用工会在浮点数和原始十六进制之间进行转换以通过CAN总线发送.
union通过@ecatmur(/sf/answers/2209049671/)通过引用以下位来讨论关于类型惩罚的大部分未实现或实现定义的性质,关于标准的豁免 -布局structs具有成员类型的"公共初始序列":
C11(6.5.2.3结构和联合成员 ; 语义):
[...]如果一个联合包含几个共享一个共同初始序列的结构(见下文),并且如果联合对象当前包含这些结构中的一个,则允许检查其中任何一个的公共初始部分.完整的工会类型的声明是可见的.如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享 共同的初始序列.
C++ 03([class.mem]/16):
如果POD-union包含两个或多个共享公共初始序列的POD结构,并且如果POD-union对象当前包含这些POD结构中的一个,则允许检查它们中的任何一个的公共初始部分.如果对应的成员具有一个或多个初始成员的序列的布局兼容类型(并且对于位字段,具有相同的宽度),则两个POD结构共享共同的初始序列.
这两个标准的其他版本有相似的语言; 从C++ 11开始,使用的术语是标准布局而不是POD.
由于不需要重新解释,这不是真正的类型惩罚,只是应用于union成员访问的名称替换.C++ 17(臭名昭着的P0137R1)的提议使得这种语言明确地使用了"访问就像其他结构成员被提名一样"的语言.
但请注意粗体 - " 在任何地方都可以看到完整类型的联合声明 " - C11中存在的条款,但在2003年,2011年或2014年的C++草案中没有任何内容(几乎完全相同,但后来的版本取代了" POD"使用新术语标准布局).在任何情况下,在union任何C++标准的相应部分中都完全没有' 类型位的可见声明.
@loop和@ Mints97,这里 - /sf/answers/1997029261/ - 显示这一行在C89中也没有出现,首先出现在C99中,然后保留在C中(尽管如此,从来没有过滤过到C++).
[剪掉 - 看我的回答]
从那以后,我的问题是:
这是什么意思?什么被归类为"可见声明"?该条款是否旨在缩小 - 或扩大 - 这种"惩罚"定义行为的背景范围?
我们是否假设C++中的这种遗漏是非常慎重的?
C++与C不同的原因是什么?C++是否只是从C89"继承"了这个,然后决定 - 或者更糟,忘记 - 与C99一起更新?
如果差异是故意的,那么 …
我需要在我的程序中有原子变量.以前我在使用std::atomic<int>,但我现在正在使用的平台没有支持C++ 0x的g ++编译器.我使用volatile int它似乎正在工作,因为我还没有在多核系统中遇到竞争条件我正在测试它.
我的问题是,如果volatile int是原子一样std::atomic<int>?此外,它是否会产生内存障碍(我也需要)?
在考虑这个问题的反例时,我提出了:
struct A
{
alignas(2) char byte;
};
Run Code Online (Sandbox Code Playgroud)
但如果这是合法的和标准的布局,它是否与布局兼容struct B?
struct B
{
char byte;
};
Run Code Online (Sandbox Code Playgroud)
此外,如果我们有
struct A
{
alignas(2) char x;
alignas(4) char y;
};
// possible alignment, - is padding
// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
// x - - - y - - - x - - - y - - -
struct B
{
char x;
char y;
}; // …Run Code Online (Sandbox Code Playgroud)