我对标准中的这一点不太确定。说我有三个这样的文件:
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 ++错误?
答案 0 :(得分:4)
可能的是你的clang使用C99内联语义。在C99中,如果您的某个函数不使用“内联”或包含“extern”,则该定义是“外部定义”,它只能在程序中出现一次。请参阅inline in C99。
在C ++中,你的程序很好。在Clang SVN中,此错误已得到修复,您的程序应该可以正常工作。
答案 1 :(得分:2)
C ++ 0X草案N3225在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.
所以,对我来说,看起来gcc是对的&amp; clang错了,但是C ++ 03中的东西仍然存在(微小的)不同的可能性。
答案 2 :(得分:1)
我认为标准的意图一直是允许通过至少一个包含inline
说明符的声明来inline
创建一个函数,但是对于它何时也存在一些不确定性迟到添加第一个inline
声明。是在定义太晚之后,还是在第一次通话之后?
我的理由是双重的,首先是7.1.1中的示例,尽管是非规范性的,主要是关于存储类说明符,但建议每个声明都不需要inline
。
其次,这个缺陷报告DR 317来自2001年(2005年投票),其中增加了“如果函数的定义在第一次声明为内联之前出现在翻译单元中,那么该程序就是格式错误。”句子。从对话中可以清楚地看出,每个声明都不需要inline
,特别是在成员函数明确定义inline
的情况下,但在原始声明没有的类主体之外没有明确的inline
。
(该缺陷报告还包含我的口头禅inline
“不仅仅是一个提示”。)
当然,一旦具有外部链接的函数是内联函数,由于一个或多个声明包括一个翻译单元中的inline
说明符,它必须被声明为{{1根据第7.1.2 / 4段其余部分的所有翻译单位。
在问题的例子中,我认为意图是inline
是一个内联函数,并且它是有效的代码,尽管标准的规范性文本在我看来并不那么明确。
答案 3 :(得分:0)
你必须在两个地方都使用inline
。