我有两个返回结构的函数,一个通过复合文字返回它,另一个初始化一个变量然后返回它:
typedef struct {
int storage[256];
} data_t;
data_t data_init_compound_literal() {
return (data_t){
.storage = {1}
};
}
data_t data_init_var() {
data_t self;
self.storage[0] = 1;
return self;
}
int main(void) {
data_t em = data_init_compound_literal();
return em.storage[0];
}
当检查godbolt(使用
-O2
)中生成的汇编代码时,似乎复合文字方法生成了更多代码行:
data_init_compound_literal:
movq $0, (%rdi)
movq %rdi, %rdx
leaq 8(%rdi), %rdi
xorl %eax, %eax
movq $0, 1008(%rdi)
movq %rdx, %rcx
andq $-8, %rdi
subq %rdi, %rcx
addl $1024, %ecx
shrl $3, %ecx
rep stosq
movl $1, (%rdx)
movq %rdx, %rax
ret
data_init_var:
movl $1, (%rdi)
movq %rdi, %rax
ret
main:
movl $1, %eax
ret
这有什么原因吗?
正如 GSerg 和 Peter Cordes 提到的,
data_t self
变量未初始化,因此编译器生成较少的汇编代码。
如果更改为
data_t self = {};
,生成的汇编代码将类似。
typedef struct {
int storage[256];
} data_t;
data_t data_init_compound_literal() {
return (data_t){
.storage = {1}
};
}
data_t data_init_var() {
data_t self = {.storage = {1}};
return self;
}
int main(void) {
data_t em = data_init_compound_literal();
return em.storage[0];
}
结果:
data_init_compound_literal:
movq $0, (%rdi)
movq %rdi, %rdx
leaq 8(%rdi), %rdi
xorl %eax, %eax
movq $0, 1008(%rdi)
movq %rdx, %rcx
andq $-8, %rdi
subq %rdi, %rcx
addl $1024, %ecx
shrl $3, %ecx
rep stosq
movl $1, (%rdx)
movq %rdx, %rax
ret
data_init_var:
subq $912, %rsp
movq %rdi, %rdx
xorl %eax, %eax
movl $128, %ecx
leaq -120(%rsp), %rdi
leaq -120(%rsp), %rsi
rep stosq
movl $1, -120(%rsp)
leaq 8(%rdx), %rdi
movq %rdx, %rcx
andq $-8, %rdi
movq -120(%rsp), %rax
subq %rdi, %rcx
subq %rcx, %rsi
addl $1024, %ecx
movq %rax, (%rdx)
movq 896(%rsp), %rax
shrl $3, %ecx
movq %rax, 1016(%rdx)
movq %rdx, %rax
rep movsq
addq $912, %rsp
ret
main:
movl $1, %eax
ret