0

根据我的理解,内联函数可以在头文件中以及在源文件中(使用inline关键字),默认情况下,头文件中定义的memeber函数被编译器内联使用。共享库的cpp文件中的内联函数

我的问题是下面的源文件, add.h

#ifndef ADD_H 
#define ADD_H 
class Add { 
    public: 
     int add(int a, int b); 
}; 
#endif /* ADD_H */ 

add.cpp

#include <iostream> 
#include "add.h" 

inline int Add::add(int a, int b) { 
    std::cout << "FUNC: " << __func__ << std::endl; 
    return a + b; 
} 

的main.cpp

#include "add.h" 

int main() { 
    Add a; 
    a.add(6,7); 
    return 0; 
} 

如果我编译add.cpp和main.cpp

g++ -c add.cpp 
g++ -c main.cpp 
g++ main.o add.o 

它抱怨

main.o: In function `main': 
main.cpp:(.text+0x1a): undefined reference to `Add::add(int, int)' 
collect2: error: ld returned 1 exit status 

看着add.o符号,

 U __cxa_atexit 
       U __dso_handle 
000000000000003d t _GLOBAL__sub_I_add.cpp 
0000000000000000 t __static_initialization_and_destruction_0(int, int) 
       U std::ios_base::Init::Init() 
       U std::ios_base::Init::~Init() 
0000000000000000 r std::piecewise_construct 
0000000000000000 b std::__ioinit 

它并没有在它添加功能,我认为是因为该函数是内联的.cpp。我的问题是,当我们共享库时,是否需要在头文件中定义内联函数(示例中为add.h),以便使用该库的源文件(示例中的main.cpp)获得内联在obj创建本身上的函数? 在链接中使用-flto时没有什么区别,因为函数不在add.o中?

+1

不,不,不。如果函数内联 - 它是内联的。如果函数是在.h头文件或.cpp源文件中定义的,则无关紧要;它是否是.dll/.so共享库或.exe可执行文件无关紧要。有一点需要注意:我为什么会收到LNK2019解析的外部为我的内联函数?(https://blogs.msdn.microsoft.com/oldnewthing/20130509-00/?p=4413/) – paulsm4

+0

你必须要在使用-flto编译时间也一样。你尝试过吗? – kchoose2

回答

3

如果你在头文件中定义一个函数,每个源文件#include s表示头获取功能的副本。您会收到来自链接器的投诉,其中存在重复的定义。

如果你在一个头文件马克它inline定义一个函数,每一个源文件#include s表示头获取功能的副本,但你告诉没关系的编译器和连接器荣获抱怨。

如果你在一个源文件中定义一个函数并且不标记它inline它对其他源文件中的代码是可见的,所以他们可以调用该函数。

如果您在源文件中定义了一个函数并将其标记为inline,那么对其他源文件中的代码不可见。这就是问题所在:Addadd.cpp中定义,它的标记为inline,因此它对main.cpp不可见。您可以删除inline或将定义从add.cpp移动到add.h。如果将它移动到add.h,则可以保持原样并将其放在类定义之后,或者直接在类定义中写入,而不是将其标记为inline

链接器优化与此完全分开。在形式上,inline的意思是“如果可以的话就可以扩展这个函数”,但是编译器通常比你应该做的更好。链接器优化可以扩展函数内联,而不考虑关键字inline,而不考虑其他文件的可见性。但是代码必须是正确的,所以你必须通过修复代码来解决缺失的符号,而不是试图强制链接器优化。

+0

我认为“链接器优化”是指链接时优化,它由编译器执行,而不是链接器。你所提到的“内联”的“正式”定义远不是正式的。 –

2

您可以将函数定义放在标题中。如果它是在类定义中定义的,则暗示它是内联的。

有一个很好的回答这个问题here

+0

这就是我现在正在做的,这是我的问题,是唯一的方法? – Randolf

+2

啊,我的坏,我必须剔除那部分。在这种情况下,这里有一个类似的问题和一个很好的解释:http://stackoverflow.com/questions/3992980/c-inline-member-function-in-cpp-file –

+0

感谢您的链接,我认为如此,然后我的问题的第二部分是与-flto链接时间优化,可能是一个选项? – Randolf