[英]Simple C inline linker error
簡單的問題:
給定以下程序:
#include <stdio.h>
inline void addEmUp(int a, int b, int * result)
{
if (result) {
*result = a+b;
}
}
int main(int argc, const char * argv[])
{
int i;
addEmUp(1, 2, &i);
return 0;
}
我收到鏈接器錯誤...
Undefined symbols for architecture x86_64:
_addEmUp", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
似乎不需要編譯它。
它不需要是static
,我不會認為,根據我讀到的內容:
鏈接器錯誤內聯函數(因為這是在不同的對象中,並且處理 2 個定義而不是零)
這是一個相關的鏈接,但它是 C++,我認為在 std C 中將代碼放在標題中不是一個好習慣:
內聯函數鏈接器錯誤
編譯器信息:
cc --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix
編譯示例:
# cc main.c
Undefined symbols for architecture x86_64:
"_addEmUp", referenced from:
_main in main-sq3kr4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocatio
第 6.7.4 節的第 7 段說:
任何具有內部鏈接的函數都可以是內聯函數。 對於具有外部鏈接的函數,以下限制適用: 如果函數是用
inline
函數說明符聲明的,則它也應在同一翻譯單元中定義。 如果翻譯單元中函數的所有文件范圍聲明都包含不帶extern
的inline
函數說明符,則該翻譯單元中的定義是內聯定義。 內聯定義不為函數提供外部定義,也不禁止在另一個翻譯單元中的外部定義。 內聯定義提供了外部定義的替代方案,翻譯器可以使用它來實現對同一翻譯單元中的函數的任何調用。 未指定對函數的調用是使用內聯定義還是外部定義。
您的文件不包含addEmUp
的外部定義,並且編譯器選擇在main
的調用中使用外部定義。
提供外部定義,或將其聲明為static inline
。
嘗試在編譯器命令中添加“-O”選項。 內聯僅在啟用優化時打開。
由於 6.9/5,該程序會導致未定義的行為(不需要診斷),有時非正式地稱為“一個定義規則”:
如果在表達式中使用了用外部鏈接聲明的標識符(而不是作為 sizeof 或 _Alignof 運算符的操作數的一部分,其結果是一個整數常量),則在整個程序中的某處應該正好有一個標識符的外部定義; 否則,將不超過一個。
您的程序使用標識符addEmUp
而沒有addEmUp
提供外部定義。 (如前所述,“內聯定義不提供函數的外部定義”)。
我們不需要開始討論函數調用調用哪個定義等等。 ODR 違規未定義且無需診斷的原因是為了讓編譯器編寫者更容易; 如果此代碼需要診斷,那么編譯器將不得不在禁用內聯優化的情況下執行檢查以檢查外部定義是否存在,這確實是在浪費時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.