当我试图编译以下项目时,收到链接器错误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.cpp
、impl2.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
是内联的?