是不同对齐指针UB之间的memcpy?

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会导致未定义的行为吗?

Jen*_*edt 5

不,memcpy不做任何关于对齐的假设.它在功能上等同于逐字节复制.

顺便说auto一下,通过不是字符类型的不同类型的左值访问对象会导致未定义的行为,无论是否对齐.这违反了有效类型规则 C11 6.5 p6和p7.