假设我有2种类型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但是我担心转让中涉及的两个derefences。
如果这不是UB,这可能是一种有效的打字方式吗?
答案 0 :(得分:5)
此代码不违反别名规则。从最新的草案(n1570),§6.5第7节:
对象的存储值只能由具有其中一个的左值表达式访问 以下类型:
- 与对象的有效类型兼容的类型,
- 与对象的有效类型兼容的类型的限定版本,
- 对应于有效类型的有符号或无符号类型的类型 对象,
- 对应于合格版本的有符号或无符号类型的类型 有效的对象类型,
- 聚合或联合类型,其中包括上述类型之一 成员(包括递归地,子集合或包含的联合的成员)或
- 字符类型
(强调我的)
我对转让中涉及的两种不满都感到担忧。
这些解除引用 使用字符类型访问存储值。
当然,如果A
的表示不是B
的有效表示,您仍然可以触发未定义的行为。
答案 1 :(得分:1)
如果目标具有声明的类型,则没有问题,但是在仅通过指针知道目标的情况下,标准是不明确的。根据绝对可怕的6.5p6写入,使用memcpy
或memmove
复制数据,或“作为字符类型数组”[无论这意味着什么]将导致源的有效类型应用于目的地。标准没有规定复制字节序列必须做什么,而不将操作视为复制“字符类型数组”。