2
使用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弱」的命令行選項:
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弱」似乎引發其他併發症。有哪些選擇(除了不內聯和固定碰撞)?
對於那些想知道什麼是典型用例的人來說:在編寫模擬組件時,有時候只需要標頭實現就很方便。不同的測試夾具最終具有相同組件類型的不同模擬實現,當所有夾具鏈接到單個測試運行器時這成爲問題。
我不明白,如果你想本地實現,爲什麼你將它們定義爲弱符號? – Kam 2014-12-04 04:28:32
@Kam編譯器將它們定義爲弱符號。制定問題的另一種方法是:如何告訴編譯器爲成員函數生成本地符號? – 2014-12-04 16:44:34