在类型之间以字节方式复制数据会破坏严格的别名吗?

时间:2017-07-19 09:23:29

标签: c language-lawyer undefined-behavior

假设我有2种类型AB具有相同的大小,我有两个变量

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但是我担心转让中涉及的两个derefences。

如果这不是UB,这可能是一种有效的打字方式吗?

2 个答案:

答案 0 :(得分:5)

此代码不违反别名规则。从最新的草案(n1570),§6.5第7节:

  

对象的存储值只能由具有其中一个的左值表达式访问   以下类型:
   - 与对象的有效类型兼容的类型,
   - 与对象的有效类型兼容的类型的限定版本,
   - 对应于有效类型的有符号或无符号类型的类型   对象,
   - 对应于合格版本的有符号或无符号类型的类型   有效的对象类型,
   - 聚合或联合类型,其中包括上述类型之一   成员(包括递归地,子集合或包含的联合的成员)或
   - 字符类型

(强调我的)

  

我对转让中涉及的两种不满都感到担忧。

这些解除引用 使用字符类型访问存储值

当然,如果A的表示不是B的有效表示,您仍然可以触发未定义的行为

答案 1 :(得分:1)

如果目标具有声明的类型,则没有问题,但是在仅通过指针知道目标的情况下,标准是不明确的。根据绝对可怕的6.5p6写入,使用memcpymemmove复制数据,或“作为字符类型数组”[无论这意味着什么]将导致源的有效类型应用于目的地。标准没有规定复制字节序列必须做什么,而不将操作视为复制“字符类型数组”。