簡體   English   中英

C++ 從另一個 cpp 文件調用內聯函數

[英]C++ call inline function from another cpp file

我試圖了解有關外部、靜態等的一些基礎知識,並嘗試了以下示例,但我不明白為什么我不能“僅僅”調用該函數,因為它(可能)是內聯的。

我的第一個文件:F1.cpp

 #include <iostream>
 
 void Modify();
 int i;

 int main() {
      i = 1;

      std::cout << "i = " << i << std::endl;
      Modify();
      std::cout << "i = " << i << std::endl;
 
      return 0;
 }

第二個文件:F2.cpp

#include <iostream>

extern int i;

inline void Modify() {
    i = 99;

    std::cout << "i = " << i << std::endl;

}

使用 F2.cpp 中的 inline 關鍵字,我得到:在我的 F1.cpp 文件中對 Modify() 的未定義引用。 刪除它,代碼編譯並正常工作。

我假設 C++ 中的 inline 關鍵字具有某種類似於 static 關鍵字的行為?

我也看過這個主題,但除了文檔說內聯函數應該始終在頭文件中這一事實之外,我不明白: .cpp 文件中的 C++ 內聯成員函數

謝謝你的幫助 !

我假設 C++ 中的inline關鍵字具有某種類似於static關鍵字的行為?

相似,但不同。 該名稱仍然具有外部鏈接,並且程序的行為就像只有一個定義(例如,該函數在任何地方都具有相同的地址,並且任何靜態變量只有一個實例)。 inline的效果是:

  • 只要所有定義都相同,就可以在多個翻譯單元中定義該函數。 常規函數只能定義一次。
  • 該函數必須在使用它的任何翻譯單元中定義。 這允許編譯器在不需要時省略非內聯定義。

您的代碼違反了第二條規則,這可能會也可能不會導致鏈接錯誤。 這就是為什么內聯函數通常需要在標題中,如果您需要在多個單元中使用它們。

根據 C++ 標准(7.1.2 函數說明符)

4....如果一個帶有外部鏈接的函數在一個翻譯單元中被聲明為內聯,則它應該在它出現的所有翻譯單元中被聲明為內聯; 不需要診斷。

4 內聯函數應在每個使用 odr 的翻譯單元中定義,並且在每種情況下都應具有完全相同的定義

在 C(C 標准的第 6.7.4 節函數說明符)中,外部函數的inline函數說明符具有不同的語義

7..內聯定義不提供函數的外部定義,也不禁止在另一個翻譯單元中的外部定義。 內聯定義提供了外部定義的替代方案,翻譯器可以使用它來實現對同一翻譯單元中的函數的任何調用。 未指定對函數的調用是使用內聯定義還是外部定義

是的, inline的含義與static非常相似。 標准 (§[basic.def.odr]/3) 的具體要求是:

內聯函數應在每個使用 odr 的翻譯單元中定義。

在這種情況下,您已經在一個翻譯單元中定義inline函數,但僅在另一個翻譯單元中聲明了它,因此您不滿足在使用它的 TU 中定義它的上述要求。

內聯函數仍然可以具有外部鏈接。 當你這樣做時,標准保證它會產生一個在整個程序中具有相同地址的函數。

以防萬一不清楚:翻譯單元基本上是一個源文件,經過預處理,因此它直接包含該源文件中的所有內容以及它包含的標題中的所有內容,減去由於#ifdef#if類的內容而跳過的任何內容#if ,等等。

當您聲明一個函數inline ,只有定義它的翻譯單元(在本例中為 F2.cpp)才能訪問該函數。 如果您改為將其放在頭文件(例如 Fh)中,並在 F1.cpp 和 F2.cpp 中#include "Fh" ,則inline函數定義兩次,每個翻譯單元一次。 通常,這會導致鏈接器錯誤,但由於您聲明了函數inline ,鏈接器不知道您的Modify()函數。

暫無
暫無

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

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