为什么无法在.cpp文件中内联函数或类成员函数定义?例如,在下面的测试示例中,如果我尝试在 cpp 文件中内联函数或类成员定义,链接器将返回一个未定义的引用错误:
测试.h
void print();
class A
{
public:
void print() const;
};
测试.cpp
#include <test.h>
inline void print()
{
// implementation
}
inline void A::print() const
{
// implementation
}
主.cpp
#include <test.h>
int main(int argc, char** argv)
{
print(); // undefined reference to `print()'
A a;
a.print(); // undefined reference to `A::print() const'
return 0;
}
我在这里读过一些答案,但我仍然不确定它是如何工作的。
问:为什么不能在.cpp文件中内联函数定义?
可以在cpp
文件中内联函数。
您不能做的是从不同的cpp
文件中访问这些inline
函数。
内联函数必须存在于使用它的每个文件中。这就是为什么它们经常出现在头文件中,因此任何需要使用它的源都包括包含它的头文件。
inline
关键字确实令人困惑,尽管对于这个用例,如果您知道其含义,它仍然很清楚。
inline
会影响需要生成的代码的要求。更具体地说,它告诉编译器它不应该预见该函数的函数指针。与往常一样,允许将内容复制到调用方中。由于内联,不必创建原始函数。 所以你没有进入test.o的函数指针。
在 main.o 中,调用此函数。因此,它尝试解析未创建的函数指针,这会导致此链接器错误。
查找这些情况可以通过例如 clang: 的编译器警告来完成:-Wundefined-inline
编辑
内联函数没有函数指针吗?不,您可以完美地获取此函数的地址并使用它并传递它。但是,由于函数的内联字符,您不能依赖此函数指针与同一函数的另一个地址相等比较。
在这种情况下,您将在目标文件中的某个位置放置函数指针。但是,在这种情况下,编译器不需要为其提供正确的损坏名称,因此可以从另一个编译单元使用它。
从 cppreference.com:
内联函数或变量(自 C++17 起(的定义必须是 存在于访问它的翻译单元中(不一定 在访问点之前(。
您的函数在test.cpp
中定义,但您是从main.cpp
访问它们的。