相同定义变量的部分类型冲突

Section type conflict for identically defined variables

本文关键字:类型 冲突 定义 变量      更新时间:2023-10-16

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

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

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

g++ -std=c++11 test.cpp(G (GCC)4.9.2 20150212(Red Hat 4.9.2-6))在以下错误中产生的结果:

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

错误并不是很有帮助,因为它没有说明为什么这应该是冲突。.ii和.s临时文件均未给出问题。实际上,.s文件中只有一个部分定义

        .section        cov,"aw",@progbits

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

有什么方法可以获取有关此信息的更多信息?看看什么精确 冲突是?还是这只是一个错误...?

消息确实非常糟糕,但这不是错误。Inline函数FOO()发生了问题。之所以发生,是因为必须在使用它们使用的每个翻译上下文中定义内联函数。在此链接中,我们可以阅读有关部分属性的信息:
" ..非初始化的变量暂时进入公共(或BSS)部分,并且可以乘以"定义"。使用"使用"部分属性更改变量进入和如果一个非初始化的变量具有多个定义,可能会导致链接器发出错误...

因此,当需要在函数main中"定义" foo函数时,链接器会在Inline函数FOO中找到以前定义的COV变量并发出错误。

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

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();

为了促进推理,让我们更改foo内联函数中定义的部分属性以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:     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

我们可以看到编译器制造 foo :: Cov ,在Cov.2 Global部分(由" U"字母签名)。当我们使用相同的部分名称(COV)时,编译器试图在主块中"定义" foo遇到以前的全球定义的COV和问题。

如果您使Inline Foo static(inline static void foo()。。:cov。