3 c memcpy language-lawyer c11
据我所知,以下代码在C11中表现出未定义的行为:
#include <string.h>
struct aaaa { char bbbb; int cccc; };
int main(void) {
unsigned char buffer[sizeof(struct aaaa)] = { 0 };
struct aaaa *pointer = &buffer[0];
return (*pointer).cccc;
}
Run Code Online (Sandbox Code Playgroud)
根据N1570第6.5.3.2节第4条,
如果为指针分配了无效值,
*则未定义一元运算符的行为.
附有一个澄清的脚注
在由一元运算
*符解除引用指针的无效值中,有一个空指针,一个与指向的对象类型不适当对齐的地址,以及一个对象在其生命周期结束后的地址.
它不太可能struct aaaa *并且unsigned char *具有相同的对齐,因此我们为其分配了无效值pointer,*pointer因此使用UB.
但是,我可以复制结构吗?
#include <string.h>
struct aaaa { char bbbb; int cccc; };
int main(void) {
unsigned char buffer[sizeof(struct aaaa)] = { 0 };
struct aaaa target;
memcpy(&target, buffer, sizeof(struct aaaa));
return target.cccc;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我们通过struct aaaa *和unsigned char *来memcpy.尽管这看起来就像第一段代码一样糟糕,我无法找到C11掌管,该代码具有UB任何措辞.这种用法memcpy会导致未定义的行为吗?
不,memcpy不做任何关于对齐的假设.它在功能上等同于逐字节复制.
顺便说auto一下,通过不是字符类型的不同类型的左值访问对象会导致未定义的行为,无论是否对齐.这违反了有效类型规则 C11 6.5 p6和p7.