我有三個頭文件in my project,它們描述對象Rational
,Complex
和RubyObject
。前兩個是模板。所有可以使用在頭文件中定義的拷貝構造函數進行相互轉換 - 除了那些從const RubyObject&
s構造Rational
和Complex
的構造函數之外,其定義爲。懶惰符號綁定失敗:找不到符號
注:那些定義是必要的。如果他們全部進入標題,您將得到circular dependency。
後來,我碰到some unresolved symbol errors與源文件中定義的兩個複製構造函數。我能夠在源文件中包含以下功能
void nm_init_data() {
nm::RubyObject obj(INT2FIX(1));
nm::Rational32 x(obj);
nm::Rational64 y(obj);
nm::Rational128 z(obj);
volatile nm::Complex64 a(obj);
volatile nm::Complex128 b(obj);
}
然後call nm_init_data()
from the library entry point in the main source file。這樣做會迫使這些符號正確鏈接。
不幸的是,我最近升級了GCC,錯誤又回來了。事實上,它似乎發生在與GCC 4.6 (e.g., on Travis-CI)略有不同的地方。
但它不是一個特定於版本的問題(正如我以前所想的)。我們在Travis CI's Ubuntu-based system上看到它,它運行GCC 4.6。但是我們沒有在具有GCC 4.8.1或4.8.2的Ubuntu機器上看到它。但是我們做在帶有4.8.2的Mac OS X機器上看到它 - 而不是與4.7.2一樣的機器。關閉優化似乎也沒有幫助。
如果我在我的圖書館運行nm
,象徵絕對是不確定的:
$ nm tmp/x86_64-darwin13.0.0/nmatrix/2.0.0/nmatrix.bundle |grep RationalIsEC1ERKNS
U __ZN2nm8RationalIsEC1ERKNS_10RubyObjectE
00000000004ca460 D __ZZN2nm8RationalIsEC1ERKNS_10RubyObjectEE18rb_intern_id_cache
00000000004ca458 D __ZZN2nm8RationalIsEC1ERKNS_10RubyObjectEE18rb_intern_id_cache_0
我不知道爲什麼有兩個定義項,其是從屬於未定義的符號,但我也沒有儘可能多地瞭解編譯器。
它也像拷貝構造函數是爲Rational
模板的每個版本的未定義的符號:
__ZN2nm8RationalIiEC1ERKNS_10RubyObjectE
__ZN2nm8RationalIsEC1ERKNS_10RubyObjectE
__ZN2nm8RationalIxEC1ERKNS_10RubyObjectE
「嗯,這很奇怪,」我想。 「Complex64
和Complex128
也被稱爲nm_init_data
函數,但它們都可以正確解析 - 並且不在nm -u
輸出中列出。」所以我在Rational複製構建之前嘗試添加volatile
,認爲編譯器可能會優化我們不想優化的內容。但是,這並沒有解決它,可悲的是。這做,有一點需要注意:
void nm_init_data() {
volatile VALUE t = INT2FIX(1);
volatile nm::RubyObject obj(t);
volatile nm::Rational32 x(const_cast<nm::RubyObject&>(obj));
volatile nm::Rational64 y(const_cast<nm::RubyObject&>(obj));
volatile nm::Rational128 z(const_cast<nm::RubyObject&>(obj));
volatile nm::Complex64 a(const_cast<nm::RubyObject&>(obj));
volatile nm::Complex128 b(const_cast<nm::RubyObject&>(obj));
}
需要說明的是,現在我得到確切同樣的錯誤,但對於複雜的對象,而不是。哎呀!
dyld: lazy symbol binding failed: Symbol not found: __ZN2nm7ComplexIdEC1ERKNS_10RubyObjectE
Referenced from: /Users/jwoods/Projects/nmatrix/lib/nmatrix.bundle
Expected in: flat namespace
dyld: Symbol not found: __ZN2nm7ComplexIdEC1ERKNS_10RubyObjectE
Referenced from: /Users/jwoods/Projects/nmatrix/lib/nmatrix.bundle
Expected in: flat namespace
這是完全荒謬的。下面是這兩個函數的定義,相同的源文件作爲nm_init_data()
功能:
namespace nm {
template <typename Type>
Complex<Type>::Complex(const RubyObject& other) {
// do some things
}
template <typename Type>
Rational<Type>::Rational(const RubyObject& other) {
// do some other things
}
} // end of namespace nm
提示:有一兩件事值得一提的是,當nm_init_data()
被調用,不會發生錯誤(即,當庫被加載時)。事情發生得很晚,在另一次調用這些麻煩的功能時。
如何一勞永逸解決這個問題,以及其他人喜歡它?
另外值得注意的是,'nm_init_data()'和庫入口點都在'extern「C」{}'塊中聲明。 –
gcc 4。6我在使用它時遇到了很多問題 –