【发布时间】:2017-07-19 09:23:29
【问题描述】:
假设我有两种大小相同的A 和B,并且我有两个变量
A a = ... ; // Initialized to some constant of type A
B b;
如果我将 a 的内容复制到 b 使用类似 -
assert(sizeof(A) == sizeof(B));
size_t t;
for( t=0; t < sizeof(A); t++){
((char*)&b)[t] = ((char*)&a)[t];
}
这是否违反了 C 的严格别名规则?
我知道将指针指向 char* 并读取它不是 UB,但我担心分配中涉及的两种取消引用。
如果这不是 UB,这可以成为类型双关语的有效方式吗?
【问题讨论】:
-
这不是由于严格的别名造成的 UB(实际上,您在这里没有别名,除了
char*,这是允许的)。这是 UB,因为您可能刚刚用陷阱表示填充 B。您正式复制的位模式表示的值使b处于不确定状态,IIRC。 -
@StoryTeller 如果保证
B是一个没有陷阱表示的类型,这是“OK”吗? -
Well, yeah。但该标准并没有向您承诺任何有意义的语义。
-
@StoryTeller,如果
A和B是具有完全相同字段的两种结构类型,我是否可以期望行为与单独复制每个字段相同。因为该标准保证,如果两个结构使用相同的成员定义,则任何实现都必须具有相同的内存布局。 -
标准确实保证了这一点。我想你应该没事。任何被复制的填充位的内容都不会干扰,因为它们只是未指定的。所有相应的成员将正确复制他们的值。作为旁注,我认为您的循环应该替换为对
memcpy的调用。它需要更少的投射(反过来看起来更干净)。
标签: c language-lawyer undefined-behavior