Why does return of a compound literal (C99) generate more assembly code?

86 Views Asked by At

I have two functions that return a struct, one returns it via compund litearal and the other initializes a variable to then return it:

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];
}

When inspecting the generated assembly code in godbolt (with -O2), it seems that the compound liteal approach genereates more lines of code:

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

Is there a reason for this?

1

There are 1 best solutions below

1
edugomez102 On BEST ANSWER

As GSerg and Peter Cordes mentioned, the data_t self variable is not initialized so the compiler generates less assembly code.

If changed to data_t self = {}; the resulting assembly code would be similar.

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];
}

Results on:

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