I am trying to understand how the "static"
modifier works in C, I went looking for its meaning and everything I found seemed a bit vague.
It is a modifier to allow the values of a variable to exist until the end of the program execution.
I understood what it means and its purpose, but beyond this definition I wanted to understand how it works underneath, so I generated the assembly of the C code
char *thing(char *a){ char *b; b = malloc(3); b[0] = 'y'; b[1] = '\0'; return (b);}char *some(int fd){ static char *a = "happened"; a = thing(a); return (a);}
I create another code with non-static a
variable and got this
/* With static variable */ .file "static_test.c" .text .globl thing .type thing, @functionthing:.LFB6: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $32, %rsp movq %rdi, -24(%rbp) movl $3, %edi call malloc@PLT movq %rax, -8(%rbp) movq -8(%rbp), %rax movb $121, (%rax) movq -8(%rbp), %rax addq $1, %rax movb $0, (%rax) movq -8(%rbp), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc.LFE6: .size thing, .-thing .globl some .type some, @functionsome:.LFB7: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movl %edi, -4(%rbp) movq a.0(%rip), %rax movq %rax, %rdi call thing movq %rax, a.0(%rip) movq a.0(%rip), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc.LFE7: .size some, .-some .section .rodata.LC0: .string "happened" .section .data.rel.local,"aw" .align 8 .type a.0, @object .size a.0, 8a.0: .quad .LC0 .ident "GCC: (GNU) 12.1.0" .section .note.GNU-stack,"",@progbits
/* no static variable */ .file "nostatic_test.c" .text .globl thing .type thing, @functionthing:.LFB6: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $32, %rsp movq %rdi, -24(%rbp) movl $3, %edi call malloc@PLT movq %rax, -8(%rbp) movq -8(%rbp), %rax movb $121, (%rax) movq -8(%rbp), %rax addq $1, %rax movb $0, (%rax) movq -8(%rbp), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc.LFE6: .size thing, .-thing .section .rodata.LC0: .string "happened" .text .globl some .type some, @functionsome:.LFB7: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $32, %rsp movl %edi, -20(%rbp) leaq .LC0(%rip), %rax movq %rax, -8(%rbp) movq -8(%rbp), %rax movq %rax, %rdi call thing movq %rax, -8(%rbp) movq -8(%rbp), %rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc.LFE7: .size some, .-some .ident "GCC: (GNU) 12.1.0" .section .note.GNU-stack,"",@progbits
The question would be, what is happening and the difference between the two assembly codes and how does this behave at compile time and at program execution time.