内联是否确定内部链接? [英] Does inline determine internal linkage?

查看:81
本文介绍了内联是否确定内部链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试内联函数.我认为它应该如何工作:

I'm trying to extern an inline function. How I thought it should work:

//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }

但是出现链接错误.然后通过阅读(" 1),必须声明<每个翻译单元中的code> inline .).我尝试过的:

But getting link error. Then by reading this ("1) It must be declared inline in every translation unit."). What I've tried:

//a.cpp
inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }

仍然出现链接错误.但是现在,尝试一些我不知道自己在做什么的事情:

Still getting link error. But now, trying something that I don't know what I'm doing:

//a.cpp
extern inline void f(int) {}
//b.cpp
extern inline void f(int);
int main() { f(4); }

有效.这里发生了什么事?在将 extern 添加到所有内容之前, a.cpp 中的 f 是否具有内部链接?

It works. What's happening here? Before adding extern to everything, f in a.cpp had internal linkage?

我正在将MSVC 2017(v141)与/permissive-/std:c ++ 17

I'm using MSVC 2017 (v141) with /permissive- and /std:c++17

推荐答案

我正在尝试内联函数.

I'm trying to extern an inline function.

没有理由将 extern 与函数一起使用.请参阅存储时间-链接.默认情况下,函数具有外部链接;为了没有外部链接,需要做一些特殊的事情(即,将其放在匿名名称空间中或声明为 static ).因此,内联函数的正常使用已经显示出外部链接,不需要 extern 关键字.

There is no reason to use extern with a function. See storage duration - linkage. Functions have external linkage by default; in order to not have external linkage, something special needs to be done (i.e. put it in an anonymous namespace or declare it static). So the normal use of an inline function already exhibits external linkage with no need for the extern keyword.

我认为它应该如何工作:

How I thought it should work:

//a.cpp
inline void f(int) {}
//b.cpp
extern void f(int);
int main() { f(4); }

然后通过阅读(" 1")在每个翻译单元中声明为 inline .).

Then by reading this ("1) It must be declared inline in every translation unit.").

该引用是正确的,但是要在其表示的地方多一些查找.内联函数的定义必须存在于被访问的翻译单元中."您的示例在 b.cpp 中声明了 f ,但没有定义.如果要从 b.cpp 调用 f ,则需要该翻译单元中的完整定义,如:

That reference is correct, but look up a bit more where it says "The definition of an inline function [...] must be present in the translation unit where it is accessed [...]." Your example has a declaration of f in b.cpp, but not a definition. If you are going to call f from b.cpp, you need the full definition in that translation unit, as in:

inline void f(int) {}

(这与 a.cpp 中存在的相同代码.)如果不使用花括号,则您有一个声明但没有定义,这使得调用是违法的f 来自该翻译单元.

(This is the same code that exists in a.cpp.) If you leave off the curly braces, then you have a declaration but not a definition, making it illegal to call f from that translation unit.

基本上,除非在内部文件中指定内部链接,否则很难在头文件中定义内联函数.这是因为每个使用内联函数的源文件都需要自己的函数主体副本,这意味着如果更改函数,则需要在多个文件中进行更改.钱币.不要这样在头文件中定义每个 inline 函数.如果您想在源文件中定义一个,则可能会误解" inline "的含义.

Basically, it is a real pain to define an inline function outside a header file, unless you give it internal linkage. That's because each source file that uses the inline function would need its own copy of the function body, meaning that if you change the function, you need to make that change in multiple files. Oof. Don't do it. Define each of your inline functions in a header file. If you think you want to define one in a source file, you probably misunderstand what "inline" means.

"内联"是什么意思?

What does "inline" mean?

就编译器而言, inline 关键字(几乎)没有任何意义.它只是函数定义上的一个标志,该标志被传播到目标代码中,以便 linker 能够看到它.编译器会像处理其他任何函数一样处理该函数.该函数可以正常调用,也可以内联–对其进行调用.就像其他任何功能一样.

As far as the compiler is concerned, the inline keyword means (almost) nothing. It is just a flag on a function definition that gets propagated into the object code so that the linker sees it. The compiler processes the function just as it would any other function. The function may be called normally, or calls to it might be inlined – just like any other function.

一种使用编译器可能会使用 inline 标志执行某些操作的情况是,使用了一个声明为 inline 的函数,但缺少定义.这是在链接程序接管之前可以捕获的错误.它没有必须被编译器捕获,但是可以.(如果没有被编译器捕获,它将被链接器捕获.)

The one case where the compiler might do something with the inline flag is when a function is declared inline, is used, but lacks a definition. This is an error that can be caught before the linker takes over. It does not have to be caught by the compiler, but it can be. (If not caught by the compiler, it would be caught by the linker.)

进入链接阶段.链接器看到 inline 标志时,它将挂起该函数的一定义规则.链接器期望在编译器优化后仍在使用该功能的每个翻译单元中看到该功能的定义.它可以选择这些定义中的任何一个作为最终实现.因此,所有定义都必须匹配的原因.

Moving on to the linking stage. When the linker sees the inline flag, it suspends the one-definition rule for that function. The linker will expect to see a definition of the function in each translation unit that still uses the function after the compiler's optimizations. It gets to choose any one of those definitions to serve as the final implementation. Hence the reason that all definitions must match.

就是这样. inline 关键字基本上意味着函数定义在头文件中.它告诉链接器该定义出现在多个翻译单元中时不要抱怨,因为这是预期的.

And that's about it. The inline keyword basically means that the function definition is in a header file. It tells the linker to not complain when that definition appears in multiple translation units, because that is expected.

回到问题,似乎是要声明一个 inline 函数,其定义将仅出现在一个翻译单元中.换句话说,该功能将被标记为在多个翻译单元中定义,但是该定义仅在一个中.那种不一致的地方,即使不是完全矛盾的.

Going back to the question, it looks like the intent was to declare an inline function whose definition would appear in only one translation unit. In other words, the function would be flagged as defined in multiple translation units, but the definition would be in only one. Kind of inconsistent there, if not outright contradictory.

这篇关于内联是否确定内部链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆