Where are static variables stored in C and C++?

前端 未结 16 2131
自闭症患者
自闭症患者 2020-11-22 02:00

In what segment (.BSS, .DATA, other) of an executable file are static variables stored so that they don\'t have name collision? For example:


foo.c:                  


        
相关标签:
16条回答
  • 2020-11-22 02:43

    I don't believe there will be a collision. Using static at the file level (outside functions) marks the variable as local to the current compilation unit (file). It's never visible outside the current file so never has to have a name that can be used externally.

    Using static inside a function is different - the variable is only visible to the function (whether static or not), it's just its value is preserved across calls to that function.

    In effect, static does two different things depending on where it is. In both cases however, the variable visibility is limited in such a way that you can easily prevent namespace clashes when linking.

    Having said that, I believe it would be stored in the DATA section, which tends to have variables that are initialized to values other than zero. This is, of course, an implementation detail, not something mandated by the standard - it only cares about behaviour, not how things are done under the covers.

    0 讨论(0)
  • 2020-11-22 02:46

    Where your statics go depends on whether they are zero-initialized. zero-initialized static data goes in .BSS (Block Started by Symbol), non-zero-initialized data goes in .DATA

    0 讨论(0)
  • 2020-11-22 02:46

    This is how (easy to understand):

    0 讨论(0)
  • 2020-11-22 02:46

    I tried it with objdump and gdb, here is the result what I get:

    (gdb) disas fooTest
    Dump of assembler code for function fooTest:
       0x000000000040052d <+0>: push   %rbp
       0x000000000040052e <+1>: mov    %rsp,%rbp
       0x0000000000400531 <+4>: mov    0x200b09(%rip),%eax        # 0x601040 <foo>
       0x0000000000400537 <+10>:    add    $0x1,%eax
       0x000000000040053a <+13>:    mov    %eax,0x200b00(%rip)        # 0x601040 <foo>
       0x0000000000400540 <+19>:    mov    0x200afe(%rip),%eax        # 0x601044 <bar.2180>
       0x0000000000400546 <+25>:    add    $0x1,%eax
       0x0000000000400549 <+28>:    mov    %eax,0x200af5(%rip)        # 0x601044 <bar.2180>
       0x000000000040054f <+34>:    mov    0x200aef(%rip),%edx        # 0x601044 <bar.2180>
       0x0000000000400555 <+40>:    mov    0x200ae5(%rip),%eax        # 0x601040 <foo>
       0x000000000040055b <+46>:    mov    %eax,%esi
       0x000000000040055d <+48>:    mov    $0x400654,%edi
       0x0000000000400562 <+53>:    mov    $0x0,%eax
       0x0000000000400567 <+58>:    callq  0x400410 <printf@plt>
       0x000000000040056c <+63>:    pop    %rbp
       0x000000000040056d <+64>:    retq   
    End of assembler dump.
    
    (gdb) disas barTest
    Dump of assembler code for function barTest:
       0x000000000040056e <+0>: push   %rbp
       0x000000000040056f <+1>: mov    %rsp,%rbp
       0x0000000000400572 <+4>: mov    0x200ad0(%rip),%eax        # 0x601048 <foo>
       0x0000000000400578 <+10>:    add    $0x1,%eax
       0x000000000040057b <+13>:    mov    %eax,0x200ac7(%rip)        # 0x601048 <foo>
       0x0000000000400581 <+19>:    mov    0x200ac5(%rip),%eax        # 0x60104c <bar.2180>
       0x0000000000400587 <+25>:    add    $0x1,%eax
       0x000000000040058a <+28>:    mov    %eax,0x200abc(%rip)        # 0x60104c <bar.2180>
       0x0000000000400590 <+34>:    mov    0x200ab6(%rip),%edx        # 0x60104c <bar.2180>
       0x0000000000400596 <+40>:    mov    0x200aac(%rip),%eax        # 0x601048 <foo>
       0x000000000040059c <+46>:    mov    %eax,%esi
       0x000000000040059e <+48>:    mov    $0x40065c,%edi
       0x00000000004005a3 <+53>:    mov    $0x0,%eax
       0x00000000004005a8 <+58>:    callq  0x400410 <printf@plt>
       0x00000000004005ad <+63>:    pop    %rbp
       0x00000000004005ae <+64>:    retq   
    End of assembler dump.
    

    here is the objdump result

    Disassembly of section .data:
    
    0000000000601030 <__data_start>:
        ...
    
    0000000000601038 <__dso_handle>:
        ...
    
    0000000000601040 <foo>:
      601040:   01 00                   add    %eax,(%rax)
        ...
    
    0000000000601044 <bar.2180>:
      601044:   02 00                   add    (%rax),%al
        ...
    
    0000000000601048 <foo>:
      601048:   0a 00                   or     (%rax),%al
        ...
    
    000000000060104c <bar.2180>:
      60104c:   14 00                   adc    $0x0,%al
    

    So, that's to say, your four variables are located in data section event the the same name, but with different offset.

    0 讨论(0)
提交回复
热议问题