Section type conflict for identically defined variables

前端 未结 1 1545
臣服心动
臣服心动 2021-01-17 10:51

This question arose in the context of this question: Find unexecuted lines of c++ code

When searching for this problem most people tried to add code and variables in

相关标签:
1条回答
  • 2021-01-17 11:13

    The message is indeed very bad, but it isn't a bug. The problem here occurs with inline function foo() and occurs because Inline functions must be defined in each translation context where they used. In this link we can read about section attribute:
    "..uninitialized variables tentatively go in the common (or bss) section and can be multiply ‘defined’. Using the section attribute changes what section the variable goes into and may cause the linker to issue an error if an uninitialized variable has multiple definitions...".

    Thus, when the foo function needs to be 'defined' in function main, the linker finds cov variable previously defined in inline function foo and issues the error.

    Let’s make the pre-processor's work and expand COV() define to help to clarify the problem:

    inline  void foo()
    {
        do { static unsigned cov[2] __attribute__((section("cov"))) = { 40, cover() }; } while(0);
    }
    
    int main(int argc, char *argv[]) {
        do { static unsigned cov[2] __attribute__((section("cov"))) = { 44, cover() }; } while(0);
    
        if (argc > 1)
            do { static unsigned cov[2] __attribute__((section("cov"))) = { 47, cover() }; } while(0);
    
        if (argc > 2)
                 foo();
    

    To facilitate reasoning, let’s alter the section attribute of definition in foo inline function to cov.2 just to compile the code. Now we haven’t the error, so we can examine the object (.o) with objdump:

    objdump -C -t -j cov ./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o
    
    ./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o:     file format elf64-x86-64
    
    SYMBOL TABLE:
    0000000000000000 l    d  cov    0000000000000000 cov
    0000000000000000 l     O cov    0000000000000008 main::cov
    0000000000000008 l     O cov    0000000000000008 main::cov
    
    objdump -C -t -j cov.2 ./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o 
    
    ./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o:     file format elf64-x86-64
    
    SYMBOL TABLE:
    0000000000000000 l    d  cov.2  0000000000000000 cov.2
    0000000000000000 u     O cov.2  0000000000000008 foo()::cov
    

    We can see that compiler makes foo::cov, in section cov.2 GLOBAL (signed by ‘u’ letter). When we use the same section name (cov), the compiler, trying to ‘define’ foo in main block encounters a previous globally defined cov and the issues the error.

    If you make inline foo static (inline static void foo() . . .), which avoids compiler to emit code for inline function and just copies it at expansion time, you’ll see the error disappears, because there isn't a global foo::cov.

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