【发布时间】:2021-09-18 04:39:46
【问题描述】:
为什么 gcc 会为以下函数创建不同的汇编代码以将结构清零?
typedef struct {
char a;
int b;
} A;
void f(A *x) {
memset(x, 0, sizeof(*x));
}
void g(A *x) {
x->a = 0;
x->b = 0;
}
void h(A *x) {
*x = (A) {0};
}
大会 (-Ofast):
f:
mov QWORD PTR [rdi], 0
ret
g:
mov BYTE PTR [rdi], 0
mov DWORD PTR [rdi+4], 0
ret
h:
mov QWORD PTR [rdi], 0
ret
我认为这是因为数据结构的填充,但是 gcc 是否不允许覆盖填充字节,因为它们无论如何都不能使用?我实际上希望f、g 和h 产生相同的代码。
谢谢
【问题讨论】:
-
事实上,如果这个结构是联合的一个字段,它的附加字段与填充重叠,它会在行为上有所不同。
-
@EugeneSh。您指的是更改后的填充字节吗?如果是这样,可观察到的效果仍然是相同的(因为它们不应该携带任何信息)。我认为您无法保证填充字节会发生什么,我认为将它们归零和保持不变都是符合要求的。
-
@EugeneSh。可观察行为的差异是由于未指定的行为。
-
@EugeneSh。 6.2.6.1/6 供参考。
-
@IanAbbott 是的,也正要发布这个参考:)这里是链接port70.net/~nsz/c/c11/n1570.html#6.2.6.1p6。 p7 似乎也很相关
标签: c gcc language-lawyer padding memset