对于相同定义的变量,节类型冲突 [英] Section type conflict for identically defined variables

查看:152
本文介绍了对于相同定义的变量,节类型冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题出现在这个问题的上下文中:查找未执行的行的c ++代码



当搜索这个问题时,大多数人试图将代码和变量添加到同一部分 - 但这绝对不是问题。这是一个最小的工作示例:

  unsigned cover(){return 0; } 
$ b $ #define COV()do {static unsigned cov [2] __attribute __((section(cov)))= {__LINE__,cover()}; } while(0)

inline void foo(){
COV();

$ b $ int main(int argc,char * argv [])
{
COV();

if(argc> 1)
COV();

if(argc> 2)
foo();

返回0;
}

其结果是 g ++ -std = c ++ 11 test.cpp (g ++(GCC)4.9.2 20150212(Red Hat 4.9.2-6))出现以下错误:

  test.cpp:6:23:error:cov导致与cov 
COV();
^
test.cpp:11:30:note:'cov'在这里被声明
COV();
^

虽然这个错误并不是很有帮助,应该是一个冲突。 .ii和.s临时文件都没有提示可能是什么问题。事实上,在.s文件中只有一个部分定义

  .section cov,aw,@ progbits 

,我不明白为什么下一个定义应该与此冲突(aw,@ progbits是正确的。 ..)。


有什么方法可以获得更多关于此的信息?看看准确的
冲突是什么?或者这只是一个错误...?



解决方案

消息确实非常糟糕,但它不是一个错误。
这里的问题出现在内联函数foo()
中,并且因为内联函数必须在它们使用的每个翻译上下文中定义。在此链接我们可以阅读关于部分属性:

..未初始化的变量暂时进入公共(或bss)部分并且可以被定义相乘。使用section属性可以改变变量的哪一部分进入并
可能会导致链接器发出错误,如果未初始化的变量有多个定义...



因此,当foo函数需要在main函数中被定义,链接器找到之前在内联函数foo中定义的cov变量并发布错误。

让我们让预处理器的工作并扩展COV()定义以帮助澄清问题:

  inline void foo()
{
{do {static unsigned cov [2] __attribute __((section(cov)))= {40,cover()}; (0);

$ b $ int main(int argc,char * argv []){
do {static unsigned cov [2] __attribute __((section(cov)))= {44,cover()}; (0); (argc> 1)
do {static unsigned cov [2] __attribute __((section(cov)))= {47,cover()};

。 (0);

if(argc> 2)
foo();

为了便于推理,让我们将foo内联函数中的定义的section属性更改为cov.2,编译代码。现在我们没有错误,所以我们可以用objdump来检查对象(.o):

  objdump -C -t -j cov ./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o 

./cmake-build-debug/CMakeFiles/stkovf.dir/main.cpp.o:文件格式elf64-x86-64

符号表:
0000000000000000 ld 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:文件格式elf64-x86-64

符号表:
0000000000000000 ld cov.2 0000000000000000 cov.2
0000000000000000 u O cov.2 0000000000000008 foo():: cov

我们可以看到,编译器制作 foo :: cov ,部分cov.2 GLOBAL(由'u'字母签名)。
当我们使用相同的段名(cov)时,编译器试图在main块中'定义'foo遇到以前全局定义的cov,并且发出错误。

如果您使内联foo static(内联static void foo()。。。。),避免编译器为内联函数发出代码并将其复制到扩展时间,你会看到错误消失,因为没有全局foo :: cov。


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 into the same section - but this is definitely not the problem here. Here is a minimal working example:

unsigned cover() { return 0; }

#define COV() do { static unsigned cov[2] __attribute__((section("cov"))) = { __LINE__, cover() }; } while(0)

inline void foo() {
        COV();
}

int main(int argc, char* argv[])
{
        COV();

        if (argc > 1)
                COV();

        if (argc > 2)
                foo();

        return 0;
}

which results with g++ -std=c++11 test.cpp (g++ (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)) in the following error:

test.cpp:6:23: error: cov causes a section type conflict with cov
  COV();
                       ^
test.cpp:11:30: note: ‘cov’ was declared here
         COV();
                              ^

The error is not very helpful though, as it does not state why this is supposed to be a conflict. Both the .ii and .s temporary files give no hint as to what might be the problem. In fact there is only one section definition in the .s file

        .section        cov,"aw",@progbits

and I don't see why the next definition should conflict with this ("aw",@progbits is correct...).

Is there any way to get more information on this? See what the precise conflict is? Or is this just a bug...?

解决方案

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.

这篇关于对于相同定义的变量,节类型冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆