内联限定符源于原型还是定义?

发布于 2024-10-16 09:54:31 字数 908 浏览 8 评论 0原文

我对标准中的这一点不太确定。假设我有三个这样的文件:

foo.h

#include <iostream>

inline void foo();

void foo()
{
   std::cout << "Foo" << std::endl;
}

foo.cpp:

#include "foo.h"

void baz();

int main()
{
   baz();
   foo();
}

bar.cpp

#include "foo.h"

void baz()
{
   foo();
}

现在, foo 的定义将被编译为两个文件编译单元 foo.o 和 bar.o。如果我理解正确,内联函数将避免链接器冲突。 G++ 编译并链接它很好,但是使用 clang++ 2.8 我收到此错误:

/tmp/cc-7RdmYP.o: In function `foo()':
bar.cpp:(.text+0x50): multiple definition of `foo()'
/tmp/cc-LW3id3.o:foo.cpp:(.text+0x50): first defined here
collect2: ld returned 1 exit status

看来 clang++ 没有将 void foo() 视为内联函数。然而,当我将内联添加到定义中时,它确实工作得很好。

我是否还必须在此处将内联添加到 void foo() 才能将其视为内联函数,还是这是一个 clang++ 错误?

I'm not quite sure about this in the standards. Say I have three files like this:

foo.h

#include <iostream>

inline void foo();

void foo()
{
   std::cout << "Foo" << std::endl;
}

foo.cpp:

#include "foo.h"

void baz();

int main()
{
   baz();
   foo();
}

bar.cpp

#include "foo.h"

void baz()
{
   foo();
}

Now, the definition for foo will be compiled into both compilation units foo.o and bar.o. If I understand it correctly, having inlined functions will avoid linker collition. G++ compiled and links this just fine, but with clang++ 2.8 I get this error:

/tmp/cc-7RdmYP.o: In function `foo()':
bar.cpp:(.text+0x50): multiple definition of `foo()'
/tmp/cc-LW3id3.o:foo.cpp:(.text+0x50): first defined here
collect2: ld returned 1 exit status

It seems that clang++ does not see void foo() as an inlined function. It does however, work fine when I add inline to the definition as well.

Do I have to add inline to void foo() as well here to have it be seen as an inlined function, or is this a clang++ bug?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

肥爪爪 2024-10-23 09:54:31

您的 clang 很可能使用 C99 内联语义。在 C99 中,如果您的某个函数不使用“内联”或包含“外部”,则该定义是“外部定义”,只能在程序中出现一次。请参阅C99 中的内联

在C++中,你的程序没问题。在 Clang SVN 中,此错误已得到修复,您的程序应该可以正常工作。

Odds are that your clang uses C99 inline semantics. In C99, if one of your functions doesn't use "inline" or does include "extern", then the definition is an "external definition", which can only appear once in the program. See inline in C99.

In C++, your program is fine. In Clang SVN, this bug has been fixed and your program should work fine.

无言温柔 2024-10-23 09:54:31

C++0X 草案 N3225 在 7.1.2 函数说明符中说:

  • 条款 2:带有内联说明符的函数声明声明内联函数
  • 条款 4:内联函数应在使用 odr 的每个翻译单元中定义,并且在每种情况下都应具有完全相同的定义。

因此,对我来说,看起来 gcc 是正确的 & clang 错了,但是 C++03 中的情况仍然有(很小的)不同的可能性。

C++0X draft N3225 says in 7.1.2 Function specifiers:

  • clause 2: A function declaration with an inline specifier declares an inline function
  • clause 4: An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case.

So, to me, it looks like gcc is right & clang wrong, but there's still a (slim) chance that things were (are?) different in C++03..

荆棘i 2024-10-23 09:54:31

我相信该标准的目的始终是允许通过至少一个包含 inline 说明符的声明来使函数内联,但何时存在一些不确定性添加第一个 inline 声明已经太晚了。是在定义之后太晚了,还是在第一次调用之后?

我对此的推理有两个方面,首先是 7.1.1 中的示例,尽管不规范且主要与存储类说明符有关,但表明并非每个声明都需要 inline

其次,2001 年的缺陷报告 DR 317 (于 2005 年投票),其中添加了“如果函数的定义出现在翻译单元中在其第一个内联声明之前,则该程序格式错误”。句子。从对话中可以清楚地看出,并不是每个声明都需要 inline,特别是在显式定义 inline 但在类外部的成员函数的情况下原始声明没有显式内联的主体。

(该缺陷报告还包含我的口头禅:内联“不仅仅是一个提示”。)

当然,一旦具有外部链接的函数就是一个内联函数,因为在一个翻译单元中包含 inline 说明符的一个或多个声明,必须根据第 7.1.2/4 段的其余部分在所有翻译单元中声明 inline

在问题的示例中,我相信其意图是 foo 是一个内联函数,并且它是有效的代码,尽管在我看来,标准的规范文本似乎不太清楚。

I believe that the intention of the standard has always been to allow a function to be made inline by having at least one declaration including the inline specifier but there was some uncertainty about when it was too late to add the first inline declaration. Was after the definition too late, or after the first call?

My reasoning for this is two fold, first the examples in 7.1.1, although non-normative and principally about storage class specifiers, suggest that inline isn't required on every declaration.

Secondly this defect report DR 317 from 2001 (voted in in 2005) which adds the "If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed." sentence. It is clear from the conversation that it was intented that inline isn't required on every declaration, specifically in the case of a member function defined explicitly inline but outside of the class body where the original declaration didn't have an explicit inline.

(That defect report also contains my mantra that inline is "more than a hint".)

Of course, as soon as a function with external linkage is an inline function due to one or more declarations including the inline specifier in one translation unit it must be declared inline in all translation units according to the rest of paragraph 7.1.2/4.

In the example in the question I believe that the intention is that foo is an inline function and that it is valid code although the normative text of the standard seems to me to be less clear than it could be.

夜清冷一曲。 2024-10-23 09:54:31

您必须在这两个地方使用inline

You have to use inline in both places.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文