[英]symbol not found AKA undefined symbol
大多數在 UNIX 上工作的人都會經常遇到這個惱人的錯誤。 有時它會花費更少的時間來解決,有時它會花費很多時間。
即使我經常遇到這個問題,我也需要一些關於 c/c++ 中特定錯誤的好文檔或文章
什么情況下可能會出現 Symbol not found/Undefined Symbol 錯誤。
有人可以幫我知道所有這些情況嗎?
該錯誤與 UNIX/Windows/任何其他操作系統無關,而是與語言本身有關。 使用編譯器提供的信息進行診斷實際上相當簡單。 通常他們會告訴您缺少什么符號,有時還會告訴您在哪里使用它。 缺少符號的主要原因是:
如果您打算定義符號但與聲明不匹配(聲明為void foo( int, double );
,但定義為void foo( double, int )
則第一個有點棘手。與所有其他情況一樣,編譯器將告訴您它正在尋找的確切簽名,確保您已定義該符號,而不是接近或相似的符號,如果您在聲明和定義中使用不同的調用約定,則可能是特定的極端情況,因為它們會在代碼中看起來非常相似。
在庫外部代碼的情況下,復雜性在於確定需要鏈接哪個庫才能添加該符號,這來自 lib 的文檔。 請注意,對於 static 庫,linker 命令行中庫的順序會影響結果。
為了幫助您找到實際定義的符號,您可以使用nm
(gcc,在 unix 系統中很常見)。 所以基本上你可以對你正在鏈接的 object 文件/庫運行nm
並搜索 linker 抱怨的符號。 這將有助於在順序決定差異的情況下(即符號存在,但 linker 跳過它)。
在運行時(感謝 Matthieu M. 指出),您可能會遇到與動態庫類似的問題,如果在 LD_LIBRARY_PATH 中發現錯誤版本的庫,您最終可能會得到一個沒有所需符號的庫。
盡管它們可能依賴於平台,但我有一些來自 Andreas 和 David 的觀點的“更復雜”的實例:
在大多數情況下,當您收到未找到符號/未定義符號或有時甚至是“重復符號”錯誤時,它們通常源於 linker 無法在您嘗試構建的項目中找到符號這一事實。
go 關於它的最佳方法是查看生成的 map 文件或編譯器的 output 的符號表。 它可能看起來像這樣:
這將允許您查看符號是否存在。 此外,可能還有其他深奧的問題,例如可能導致符號重復的編譯器優化,尤其是內聯匯編。 這些是最難發現的。
至於好的資源和材料,我沒有太多好的參考。 當年我去打聽的時候,大部分高級工程師其實都是從自己的經歷中吸取教訓的。
但我敢肯定,諸如此類的論壇會在那里幫助我們加快此類知識的獲取。
希望它有所幫助:)
干杯!
我假設您指的是 linker 錯誤。 以下是我認為最常見到最不常見的列表:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.