我有两个返回 struct 的函数,一个通过Compund litearal返回它,另一个初始化变量然后返回它:

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)中生成的汇编代码时,复合Liteal方法似乎生成了更多的代码行:

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

这是有原因的吗?

推荐答案

正如GSergPeter 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

C++相关问答推荐

理解C中的指针定义

错误:C中需要参数声明符

字符数组,字符指针,在一种情况下工作,但在另一种情况下不工作?

从内联程序集调用Rust函数和调用约定

将整数的.csv文件解析为C语言中的二维数组

为什么在此程序中必须使用Volatile关键字?

识别和处理c中整数溢出的最佳方法?

可以将C变量限制为特定的读/写速度吗?

我在这里正确地解释了C操作顺序吗?

是否可以通过调用两个函数来初始化2D数组?示例:ARRAY[STARTING_ROWS()][STARTING_COLUMNS()]

在libwget中启用Cookie会导致分段故障

C语言中的外部关键字

C:如何将此代码转换为与数组一起使用?

C标准关于外部常量的说明

为什么WcrTomb只支持ASCII?

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

C循环条件内的函数

Struct 内的数组赋值

如何转义包含指令中的字符?

C 中从 Unix 纪元时间转换的损坏