在hpp中声明、在cpp中实现并在另一个cpp中使用的内联函数发生链接错误



当我试图编译以下项目时,收到链接器错误undefined reference to function

header.hpp

inline void f(double*, double*, double*);

impl.cpp

inline void f(double* A, double* B, double* C){ ... }

使用.cpp

#include "header.hpp"
int main(){
double *A, *B, *C;
f(A, B, C);
return 0;
}

我用g++ -std=c++11 header.hpp impl.cpp use.cpp编译。然后Linker在文件use.cpp中说undefined reference to f

我注意到,如果我删除inline关键字,一切都很好,但我想保留它。

此外,我注意到,如果在use.cpp中我包含impl.cpp,那么一切都会正常工作,但这不是我想做的,因为我想使用文件impl.cppimpl2.cpp等生成多个二进制文件,因此硬编码其中一个也不是办法。

有没有办法让这样的项目编译和链接?

inline说明符并不是告诉编译器在进行优化时应该内联此函数。这种情况在很久以前就已经存在了,但与此同时,我们意识到编译器在做出这个决定时要做得更好:

内联关键字的初衷是作为优化器的一个指标,表明函数的内联替换比函数调用更可取,也就是说,不是执行函数调用CPU指令将控制权转移到函数体,而是执行函数体的副本而不生成调用。这避免了函数调用(传递参数并检索结果(所产生的开销,但由于函数的代码必须重复多次,因此可能会产生更大的可执行文件。

由于关键字inline的含义是不绑定的,编译器可以自由地对任何未标记为inline的函数使用inline替换,也可以自由地生成对任何标记为inlin的函数的函数调用。这些优化选择不会改变上面列出的关于多个定义和共享静态的规则。

如果要内联定义函数,则需要inline;(。在您的示例中,inline将允许您拥有

inline void f(double*, double*, double*) {}

在标题中。当链接器找到该函数的多个定义时(因为标头可以包含在多个源中(,它不会抱怨,因为您将其声明为inline

代码是要进行基准测试的,我想防止调用功能

如果消除调用函数的开销是可行的优化,编译器将意识到这一点并采取相应的行动。

内联函数或变量的定义(由于C++17(必须在访问它的翻译单元中可访问(不一定在访问点之前(。

来源:https://en.cppreference.com/w/cpp/language/inline

use.cpp无法访问f的定义,这就是为什么会出现链接器错误的原因。

为什么希望f是内联的?

最新更新