我试图了解一些关于extern,static等的基础知识,并尝试了以下示例,但我不知道为什么我无法调用该函数"只是& #34;因为它(可能)内联了。
我的第一个档案: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;
}
如果我保留inline关键字,我会得到:使用mingw在我的F1.cpp文件中对Modify()的未定义引用。 但是,如果我把它取下来,它一切正常.. 我假设C ++中的inline关键字有某种行为,比如static关键字?
我也看过这个主题,但除了文档说内联函数应该总是在头文件中这一事实之外,我还没有得到它:C++ inline member function in .cpp file
感谢您的帮助!
答案 0 :(得分:5)
根据C ++标准(7.1.2函数说明符)
4 ....如果具有外部链接的函数在一个内联中声明 翻译单位,应在所有翻译单位内联 它出现在哪;无需诊断。
和
4应在每个翻译单元中定义内联函数 它使用的次数和定义完全相同 每个案例
在C(第6.7.4节C标准的函数说明符)中,外部函数的函数说明符inline
具有不同的语义
7 ....内联定义不提供函数的外部定义,并且不禁止另一个定义外部定义 翻译单位。内联定义提供了替代 外部定义,翻译人员可以用来实现任何调用 到同一翻译单元的功能。它没有具体说明 是否对函数的调用使用内联定义或 外部定义
答案 1 :(得分:5)
我认为C ++中的
inline
关键字有某种行为,比如static
关键字?
相似,但不同。该名称仍然具有外部链接,并且程序的行为就像只有一个定义一样(例如,该函数在任何地方都具有相同的地址,并且只有一个静态变量的实例)。 inline
的影响是:
您的代码违反了第二条规则,该规则可能会也可能不会导致链接错误。这就是为什么内联函数通常需要在头文件中,如果你需要在多个单元中使用它们。
答案 2 :(得分:2)
是的,inline
的含义与static
非常相似。标准(§[basic.def.odr] / 3)的具体要求是:
内联函数应在每个使用它的翻译单元中定义。
在这种情况下,您在一个翻译单元中定义了 inline
函数,但只有在另一个翻译单元中声明它,所以你不是满足上面的要求,它在使用它的TU中定义。
内联函数仍然可以具有外部链接。执行此操作时,标准会保证它会生成一个在整个程序中具有相同地址的单个函数。
以防万一不清楚:翻译单元基本上是一个源文件,经过预处理后,所以它直接包含在该源文件中的所有内容以及它包含的标题中的所有内容,减去由于{ {1}},#ifdef
等
答案 3 :(得分:1)
声明函数inline
时,只有在其中定义的转换单元(在本例中为F2.cpp)才能访问此函数。如果你把它放在头文件(比如F.h)和F1.cpp和F2.cpp中的#include "F.h"
,那么inline
函数定义两次,每个翻译单元一次。通常,这会导致链接器错误,但由于您声明了函数inline
,链接器并不知道您的Modify()
函数。