共享库的cpp文件中的内联函数
Inline functions in cpp files of shared libraries
根据我的理解,内联函数既可以在头文件中,也可以在源文件中(使用inline关键字),默认情况下,编译器会尝试内联头文件中定义的memeber函数。
我的问题是以下源文件,add.h
#ifndef ADD_H
#define ADD_H
class Add {
public:
int add(int a, int b);
};
#endif /* ADD_H */
添加.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?
如果在头文件中定义一个函数,则#include
的每个头源文件都会获得该函数的副本。链接器会向您投诉存在重复的定义。
如果您在头文件中定义了一个函数,并将其标记为inline
,则#include
拥有该头的每个源文件都会获得该函数的副本,但您已经告诉编译器这没关系,链接器不会抱怨。
如果你在源文件中定义了一个函数,但没有将其标记为inline
,那么其他源文件中的代码可以看到它,所以他们可以调用该函数。
如果在源文件中定义函数并将其标记为inline
,则其他源文件中的代码将看不到该函数。这就是问题所在:Add
是在add.cpp
中定义的,它被标记为inline
,所以它对main.cpp
不可见。您可以删除inline
,也可以将定义从add.cpp
移动到add.h
。如果将其移动到add.h
,则可以保持原样并将其放在类定义之后,或者直接将其写入类定义中,而不将其标记为inline
。
链接器优化与此完全分离。从形式上讲,inline
的意思是"如果可以的话,在一行中扩展这个函数",但编译器通常比你更清楚应该做什么。链接器优化可以内联扩展函数,而不考虑inline
关键字,也不考虑其他文件的可见性。但是代码一开始就必须是正确的,所以你必须通过修复代码来解决缺失的符号,而不是试图强制进行一些链接器优化。
您可以将函数定义放入标头中。如果它是在类定义中定义的,那么它就意味着是内联的。
这个问题在这里有一个很好的答案
- 用C++在单独的头文件中完成函数体
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 头文件、宏和内联函数c++
- 如何使用单独文件中的派生类访问友元函数对象
- C++无法定义虚拟函数 OUTER 类和头文件
- 回溯C++不打印函数,因此文件
- 如何从另一个文件继承私有成员变量和公共函数
- 从函数角度看ID到文件路径的内部与外部映射
- 区分非成员函数和头文件中的成员函数
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 如何在其他文件中使用函数
- 整数键映射到头文件中的成员函数指针
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 用"=default"声明的函数应该只在头文件中执行
- 将单独的头文件和类定义文件链接到主函数文件 - G++ 返回重载"undefined reference to"构造函数
- C++ - 在一个函数/文件中初始化变量然后在main()/另一个文件中使用它的最佳方法是什么?
- C++单独的函数文件
- 只对单个函数/文件启用编译器优化