gpt4 book ai didi

c++ - 多个翻译单元中的内联函数

转载 作者:太空狗 更新时间:2023-10-29 20:49:51 28 4
gpt4 key购买 nike

让我们从以下一组 C++ 文件开始:

// my_class.h
struct MyClass
{
void my_func();
};

void MyClass::my_func()
{}


// f.h
void f1();
void f2();


// f1.cpp
#include "my_class.h"

void f1()
{
MyClass a;
a.my_func();
}


// f2.cpp
#include "my_class.h"

void f2()
{
MyClass a;
a.my_func();
}


// main.cpp
#include "f.h"

int main()
{
f1();
f2();

return 0;
}

我试着编译这段代码

$ g++ f1.cpp f2.cpp main.cpp

显然,链接器提示重复符号 my_func:

duplicate symbol __ZN7MyClass7my_funcEv in:
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f1-962ae7.o
/var/folders/yj/zz96q16j6vd1dq1_r3mz8hzh0000gn/T/f2-aef78c.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我的下一次尝试是将函数定义移到类定义中,所以我们得到:

struct MyClass
{
void my_func()
{}
};

运行相同的g++ 命令,程序编译成功。这是因为在类定义中定义的函数被隐式标记为 inline (§10.1.6 * 3)。

标准规定:

A function declaration (11.3.5, 12.2.1, 14.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions specified in this section shall still be respected

这似乎与 cppreference.com 上的内容有些矛盾:

Because the meaning of the keyword inline for functions came to mean "multiple definitions are permitted" rather than "inlining is preferred", [...]

据我所知,在类定义中定义一个函数会使它隐式内联,这并不一定意味着编译器会选择内联它的主体,而是将它的定义放在每个翻译单元。这是正确的吗?

第二个问题是关于模板类的。分离模板类的声明/定义是一个问题,如所述here所以我们只能在类定义中有函数定义,这使得它隐式内联,对吧?这有什么影响?

既然类是模板时我们只能选择在类定义中定义函数,那么对于不是模板的类怎么办呢?我们是否应该在源文件中定义函数,并尽可能只在 header 中保留声明?

最佳答案

So as far as I understand, having a function defined in the class definition makes it implicitly inline which does not necessarily mean that the compiler will choose to inline its body but will a definition of it in every translation unit. Is this correct?

正确。当在类内部定义时,它被标记为内联,并且可以将该定义带入多个翻译单元。编译器将为您处理。

The second question comes regarding template classes. Separating the declaration/definition of a template class is a problem, as described here so we can only have function definitions in the class definition which makes it implicitly inline, again, right? What is the impact of this?

这是不正确的。模板很特别。一旦代码被编译,它们实际上并不存在。什么是模板,是一种用于消除类或函数的方法。因此,they are implicitly inline as well允许模板包含在使用它的每个翻译单元中,以便编译器可以根据需要从中剔除具体的类/函数。这意味着您可以在类之外定义类成员函数。

Since we only have the choice of defining functions in class definitions when the class is a template, what is to be done about classes that are not template? Should we define function in source files and only keep the declaration in headers when possible?

通常您希望将您的定义放在一个 cpp 文件中。你从中得到的好处是,如果你改变了函数的实现,你只需要重新编译那个 cpp 文件。如果它们在头文件中,那么您需要重新编译包含该头文件的每个 cpp 文件,这会导致构建时间更长。

关于c++ - 多个翻译单元中的内联函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57210165/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com