假设我有一个联盟:
union foo {
char a;
int i;
}
在sizeof foo.i
>的平台上sizeof foo.a
。
如果我分配给foo.a
,那么以前属于foo.i
的其余内存会发生什么?
答案 0 :(得分:2)
未定义您未写入的内存会发生什么。编译器可以选择保持其内容不变。它可能(例如出于性能原因)用任意值覆盖先前的内容。
由于这个原因,在<?php
$arr = array('one', 'two', 'three', 'four', 'stop', 'five');
while (list(, $val) = each($arr)) {
if ($val == 'stop') {
break; /* You could also write 'break 1;' here. */
}
echo "$val<br />\n";
}
之后从foo.i
读取是未指定的行为。
答案 1 :(得分:1)
有趣的是,C11标准在6.2.6.1.7中非常清楚:
当值存储在union类型的对象的成员中时,对象表示的字节与该成员不对应但与其他成员对应的字节采用未指定的值。
不幸的是,我没有在C ++ 14标准中找到任何明确的内容。第9.5节:
在联合中,最多一个非静态数据成员可以随时处于活动状态,即at的值 大多数非静态数据成员可以随时存储在并集中。 [注意:一个特殊保证 是为了简化联合的使用:如果标准布局联合包含几个标准布局 共享公共初始序列(9.2)的结构,以及此标准布局联合类型的对象 包含一个标准布局结构,允许检查任何一个的公共初始序列 标准布局结构成员;见9.2。 - 结束说明]
这种保证非常具体,我找不到关于布局兼容成员的任何保证。然而,两种不同大小的布局兼容,不能是公共初始序列的一部分。所以我认为标准不允许检查非活动成员。
在访问值时会出现未定义的行为,但我认为未指定的值更有意义。