C++从另一个 cpp 文件调用内联函数

C++ call inline function from another cpp file

本文关键字:函数 调用 文件 另一个 cpp C++      更新时间:2023-10-16

我试图了解一些关于外部、静态等的基础知识,并尝试了以下示例,但我不明白为什么我不能调用函数"只是",因为它(可能(是内联的。

我的第一个文件: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 中的内联关键字,我得到:在我的 F1.cpp 文件中对 Modify(( 的未定义引用。删除它,代码可以编译并正常工作。

我假设 C++ 中的内联关键字具有某种行为,例如静态关键字?

我也看过这个主题,但除了文档说内联函数应该始终在头文件中这一事实之外,我不明白:C++.cpp文件中的内联成员函数

感谢您的帮助!

我假设C++中的inline关键字具有某种行为,例如static关键字?

相似,但不同。名称仍然具有外部链接,程序的行为就好像只有一个定义(例如,函数在任何地方都具有相同的地址,并且只有任何静态变量的一个实例(。inline的影响是:

  • 函数可以在多个翻译单元中定义,只要所有定义都相同即可。常规函数只能定义一次。
  • 该函数必须在使用它的任何翻译单元中定义。这允许编译器省略不需要的非内联定义。

您的代码违反了第二条规则,这可能会导致也可能不会导致链接错误。这就是为什么内联函数通常需要在标题中,如果您需要在多个单元中使用它们。

根据C++标准(7.1.2 函数说明符(

4....如果一个带有外部链接的函数在一个函数中内联声明 翻译单元,应在所有翻译单元中内联声明 它出现的地方;无需诊断。

4 应在 它是ODR使用的,并且在 每个案例

在C(C标准的6.7.4节函数说明符(中,外部函数的函数说明符inline具有不同的语义

7....内联定义不为函数提供外部定义,也不禁止在另一个函数中使用外部定义 翻译股。内联定义提供了 外部定义,翻译人员可以使用它来实现任何调用 到同一翻译单元中的函数。未指定 对函数的调用是使用内联定义还是 外部定义

是的,inline的含义与static非常相似。标准(§[basic.def.odr]/3(的具体要求是:

内联函数应在使用它的每个翻译单元中定义

在本例中,您在一个翻译单元中定义了 inline 函数,但只在另一个翻译单元中声明了它,因此您不符合上述要求,即在使用它的 TU 中定义它。

内联函数仍然可以具有外部链接。当您这样做时,标准保证它会产生一个在整个程序中具有相同地址的单个函数。

以防万一不清楚:翻译单元基本上是一个源文件,经过预处理,所以它包括直接在该源文件中的所有内容以及它包含的标头中的所有内容,减去由于 #ifdef#if 等原因而跳过的任何内容。

当您声明函数inline时,只有在其中定义的翻译单元(在本例中为 F2.cpp(可以访问此函数。如果将其放在头文件(例如 F.h(中,并在 F1.cpp 和 F2.cpp 中#include "F.h",则 inline 函数将定义两次,每个翻译单元中一次。通常,这会导致链接器错误,但由于您声明了函数inline,链接器不知道您的Modify()函数。