簡體   English   中英

引用了extern內聯函數但未定義

[英]extern inline function was referenced but not defined

我有一個函數(讓我們稱之為void foo(void) {} )我想要內聯。但我在.cpp文件中定義它。
我無法將函數移動到標題,因為它正在使用.cpp中的其他函數。



編輯:
下面的代碼就像真正的代碼一樣,不使用c ++功能。 我可以清楚地補充:

#ifdef __cplusplus
extern "C"
#endif

如果我想將下面的代碼轉換為c99,我只需要更改我的項目屬性(如果你願意,還可以更改makefile),而不是代碼 我也問c ++因為meaby它可以解決我的問題,而c99不能。
因此我的問題中的C和C ++標簽是合理的。 代碼是可移植的
看: 何時在C ++中使用extern“C”?



編輯#2
好吧,我明白我必須把foo()定義放在頭文件中。 如何從foo()調用func_a()func_b() foo()而不將它們移動到頭文件? 有沒有解決方法?




file.c / .cpp:

int    func_a (int a,    int b,    int c)    {/*...*/};
double func_b (double a, double b, double c) {/*...*/};

void   foo    (int a, double b) { // unction definition
    //...
    int myInt = func_a(a, 2, 3);
    //...
    double myDouble = func_b(1.5f, b, 3.5f);
    //...
}

file.h:

// Something before.

void foo (int a, double b); // function declaration

// Something after.



我想指出:

  • 我正在使用Visual Studio 2015。
  • 我正在寫一個相對較大的項目(~7000行代碼)。 它是物理系統的模擬。
  • file.h包含在許多其他編譯單元中。
  • foo(int, double)很小,它從file.cpp調用其他函數
  • 我想因為優化原因而使foo(int, double)內聯(我最終會使用__forceinline__
  • 我在我的程序中多次調用foo() 它也在幾個while循環中使用(每個100k +迭代),因此讓這個符號foo()不是內聯的是擴展的。
  • 我厭倦了僅限標題的庫。



我試過了:
file.c / .cpp:

extern inline
void   foo    (int a, double b) {\*...*\}; // Definition

file.h:

extern inline
void   foo    (int a, double b); // Declaration

但我一直在警告:

warning : extern inline function "foo" was referenced but not defined

我不明白為什么我會收到這個警告。



有沒有辦法:

  • 在我的.cpp文件中保持foo()定義? 但仍然使它內聯
  • foo()移到file.h ,將func_a()func_b()file.cpp ,但使func_a()func_b()符號對foo() “可見”(!並且只對foo() !)來自file.cpp
  • 還有其他解決方法嗎?


Sory我還在學習cpp而且我不知道我的問題是否清楚,或者甚至可以從.cpp文件中生成內聯函數。

在C ++中, inline關鍵字意味着:

  • 函數的主體必須存在於使用該函數的每個源文件中。
  • 所有源文件中的函數“主體”必須是逐個令牌的,並且逐個實體相同。
  • 編譯器和鏈接器必須確保它們對具有這些“多個主體”的函數很好

就是這樣。 實際上,這意味着它啟用並強制您將函數體放入頭文件中。

關鍵字本身與函數內聯無關。 只是如果編譯器希望能夠內聯函數的主體,它在編譯調用代碼時必須能夠訪問它; 換句話說,函數的主體必須位於同一源文件或該源文件包含的頭文件中。

如果要使編譯器內聯所有調用站點中的函數,並且這些調用站點發生在多個源文件中,則必須將該函數放入頭文件(並將其標記為inline )。

另一方面, 鏈接器也可以進行內聯,稱為鏈接時代碼生成或整個程序優化或類似的東西(取決於您的工具鏈的供應商)。 啟用此功能

  1. 延長你的構建時間
  2. 允許鏈接器將函數內聯到源文件中的調用站點

所以為了內聯函數,你有兩個選擇。 將函數放入頭文件,或啟用並依賴鏈接時優化來為您內聯。


在您的特定情況下,要使用__forceinline__ ,您將在頭文件中定義foo 這需要foo的定義來查看func_afunc_b聲明。 要防止名稱空間污染,您可以在foo的范圍內聲明這些函數:

inline void foo(int a, double b) { // function definition
    int func_a(int, int, int);
    double func_b(double, double, double);

    //...
    int myInt = func_a(a, 2, 3);
    //...
    double myDouble = func_b(1.5f, b, 3.5f);
    //...
}

暫無
暫無

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

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