簡體   English   中英

如何強制鏈接器在本地解析弱符號?

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

使用g ++,當兩個編譯單元“ a1.o”和“ a2.o”都定義並使用相同的弱符號時,無論在何處使用,鏈接程序都將默默地解析為該符號的第一個匹配項。 結果,應用程序的行為將取決於目標文件在鏈接器命令行上的順序。 如何確保將這些符號本地解析到每個編譯單元?

例如,作為一個極簡示例,如果我具有以下源文件:

a1.cpp:

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

a2.cpp:

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

main.cpp中:

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

並使用以下命令進行編譯:

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

輸出將取決於鏈接器命令行上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

我想要得到與使用'-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

但“ -fno-weak”似乎會導致其他並發症。 有哪些選擇(除了不內聯和修復碰撞)?

對於那些想知道什么是典型用例的人:在編寫模擬組件時,有時只有標頭實現很方便。 最終,不同的測試夾具具有相同組件類型的不同模擬實現,當所有夾具都鏈接到單個測試運行器時,這將成為一個問題。

您詢問:

有哪些選擇(除了不內聯和修復碰撞)?

使用本地namespace或匿名namespace

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

要么

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

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

對a2.cpp進行類似的更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM