简体   繁体   English

如何强制链接器在本地解析弱符号?

[英]How to force the linker to resolve weak symbols locally?

Using g++, when two compilation units "a1.o" and "a2.o" both define and use the same weak symbol, the linker will silently resolve to the first occurrence of the symbol wherever it is used. 使用g ++,当两个编译单元“ a1.o”和“ a2.o”都定义并使用相同的弱符号时,无论在何处使用,链接程序都将默默地解析为该符号的第一个匹配项。 As a result, the behavior of the application will depend on the order of the object files on the linker command line. 结果,应用程序的行为将取决于目标文件在链接器命令行上的顺序。 What can be done to ensure that these symbols are resolved locally to each compilation unit? 如何确保将这些符号本地解析到每个编译单元?

For instance, as a minimalist example, if I have the following source files: 例如,作为一个极简示例,如果我具有以下源文件:

a1.cpp: a1.cpp:

#include <iostream>
struct A
{
    void foo() {std::cerr << __FILE__ << std::endl;}
};
void bar1() {A a; a.foo();}

a2.cpp: a2.cpp:

#include <iostream>
struct A
{
    void foo() {std::cerr << __FILE__ << std::endl;}
};
void bar2() {A a; a.foo();}

main.cpp: main.cpp中:

void bar1();
void bar2();
int main()
{
    bar1();
    bar2();
}

and compile them with: 并使用以下命令进行编译:

for i in a1 a2 main ; do g++ -c -o $i.o $i.cpp ; done

The output will depend on the relative position of a1.o and a2.o on the linker command line: 输出将取决于链接器命令行上a1.o和a2.o的相对位置:

g++ -o main main.o a{1,2}.o ; ./main
a1.cpp
a1.cpp

g++ -o main main.o a{2,1}.o ; ./main
a2.cpp
a2.cpp

I'd like to get the same result as if using the '-fno-weak' command line option: 我想要得到与使用'-fno-weak'命令行选项相同的结果:

for i in a1 a2 main ; do g++ -fno-weak -c -o $i.o $i.cpp ; done
g++ -o main main.o a{1,2}.o ; ./main
a1.cpp
a2.cpp

but '-fno-weak' seems to lead to other complications. 但“ -fno-weak”似乎会导致其他并发症。 What are the alternatives (besides not inlining and fixing collisions)? 有哪些选择(除了不内联和修复碰撞)?

For those wondering what could be a typical use case: when writing mock components it is sometimes convenient to have header-only implementations. 对于那些想知道什么是典型用例的人:在编写模拟组件时,有时只有标头实现很方便。 Different test fixtures end-up having different mock implementations of the same component type, which becomes an issue when all the fixtures are linked into a single test runner. 最终,不同的测试夹具具有相同组件类型的不同模拟实现,当所有夹具都链接到单个测试运行器时,这将成为一个问题。

You asked: 您询问:

What are the alternatives (besides not inlining and fixing collisions)? 有哪些选择(除了不内联和修复碰撞)?

Use local namespace s or anonymous namespace s. 使用本地namespace或匿名namespace

a1.cpp: a1.cpp:

#include <iostream>
namespace A1_namespace
{
   struct A
   {
      void foo() {std::cerr << __FILE__ << std::endl;}
   };
}

using namespace A1_namespace;

void bar1() {A a; a.foo();}

or 要么

#include <iostream>
namespace
{
   struct A
   {
      void foo() {std::cerr << __FILE__ << std::endl;}
   };
}

void bar1() {A a; a.foo();}

Make similar changes to a2.cpp. 对a2.cpp进行类似的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM