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

问题描述 投票:0回答:2

当我尝试编译以下项目时,出现链接器错误undefined reference to function

header.hpp

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

impl.cpp

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

use.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进行编译。然后,链接程序在文件undefined reference to f中说use.cpp

[我注意到,如果删除inline关键字,一切正常,但我想保留它。

[此外,我注意到,如果在use.cpp中包含impl.cpp,那么一切也都可以正常工作,但是,这又不是我想要的,因为我想使用文件impl.cpp,[ C0]等,因此也无法对其中之一进行硬编码。

有什么方法可以使这样的项目进行编译和链接?

c++ linker inline
2个回答
4
投票

impl2.cpp并不是要告诉编译器在执行优化时应内联此函数。很久以前就是这种情况,但与此同时,人们意识到编译器在做出此决定方面要好得多:

inline关键字的初衷是作为优化程序的指示,即函数的内联替换优于函数调用,即,代替执行函数调用CPU指令将控制权转移到函数主体,执行函数主体的副本而不会生成调用。这样可以避免函数调用(传递参数和检索结果)造成的开销,但是由于必须重复执行该函数的代码多次,因此可能会导致更大的可执行文件。

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

要内联定义函数时,需要inline specifier;)。在您的示例中,inline将允许您具有]​​>

inline

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

该代码旨在进行基准测试,我想避免调用功能

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


0
投票

内联函数或变量的定义(自C ++ 17起)必须在访问它的翻译单元中可以到达(不一定在访问点之前)。>>

© www.soinside.com 2019 - 2024. All rights reserved.