以以下交易单位:
//1.cpp
#include<iostream>
extern void calll();
inline void fun()
{
std::cout<<"in fun 1\n";
}
int main()
{
fun();
calll();
return 0;
}
//2.cpp
#include<iostream>
inline void fun()
{
int i=123; //random un-used variable
char c= 99; //random un-used variable
std::cout<<"in fun 2\n";
}
void calll()
{
fun();
}
**情况1-> **像g++ 1.cpp 2.cpp
一样编译时,输出为:
in fun 1
in fun 1
**情况2-> **使用g++ 2.cpp 1.cpp
进行编译时,输出为:
in fun 2
in fun 2
在 1 和 2 的情况下,对函数fun()
的调用之一正在运行对事务中对fun()
的定义的引用其.cpp
文件的单位
在编译中首先提到,这表明inline
在默认情况下具有外部链接,因为单个定义在两个目标文件中均有效,而没有使用extern
声明
-在注释或删除 1.cpp 或 2.cpp 中的inline void fun()
的定义时,编译器会抛出错误fun() has not been defined
,这意味着的
链接器链接找到的fun()
的第一个定义,调用inline void fun()
的函数使用该定义,但它们也需要一个定义
即使未使用该定义,它们也存在于其交易单位中。在这里,我相信任何一个人在呼叫中实际使用的fun
的定义
main
或calll
具有外部链接笼-因为尚未为单个目标文件生成任何内联(单独的定义)。
如果以上观察结果是正确的,那么当编译器使用单个定义时,为什么在单个目标文件中需要一个定义?
是因为如果在情况1 或情况2 中以这种方式编译文件,实际上仍有机会插入函数
当使用-O2
进行编译时,每个目标文件都必须使用自己的inline void fun()
定义吗?
究竟可以保证功能是否被内联?
答案 0 :(得分:3)
您的示例实际上违反了one definition rule。简而言之,使用inline
函数,您可以有多个定义,前提是每个定义:
这实际上是UB。
inline
函数要求在每个使用ODR的翻译单元中都有一个定义,因此可以完全在标头中定义它们,而无需使用编译单元。
这与“内联”函数不同。 inline
仅表示该函数是用其声明“内联”定义的。编译器可以自行决定是否内联任何函数。