【发布时间】:2019-12-09 08:30:40
【问题描述】:
我正在对 VS2019 中的 C++ 内联函数进行一些(可能是奇特的)实验:
来源1:
#include "pch.h"
inline int inline_func(int i) {
return i;
}
void testinline1()
{
inline_func(0);
}
来源2:
#include "pch.h"
inline int inline_func(int i) {
return i*i ;
}
void testinline2()
{
inline_func(0);
}
主要来源:
#include "pch.h"
inline int inline_func(int i);
int main(int argc,char* argv[])
{
int i = inline_func(2);
}
根据http://en.wikipedia.org/wiki/Inline_function的“内联函数的存储类”部分,
在 C++ 中,如果需要,内联定义的函数将发出一个函数 在翻译单元之间共享,通常通过将其放入 需要它的目标文件的公共部分。功能 必须在任何地方都有相同的定义,总是使用内联 限定符。
source1和source2中inline_func的定义不同,应该会有错误,但是VS2019没有这个错误。
main() 中 i 的结果是 2,它来自 source1 中的 inline_func,这似乎是构建过程的随机选择,因为如果我在 source1 中注释 testinline1,那么我将变为 4,因为 source1 中的 inline_func如果没有在同一源中使用,将不会出现在目标文件中。当我在 source2 中注释 testinline2 时,inline_func 也会出现未定义的符号错误。
为什么会这样?这是C++没有覆盖还是只有MSVC没有覆盖?
回答后更新:
这是一个更好的例子:
来源1:
#include "pch.h"
int non_inline_func();
inline int inline_func2() {
return non_inline_func();
}
static int non_inline_func()
{
return 1;
}
int public_func1()
{
return inline_func2();
}
来源2:
#include "pch.h"
int non_inline_func();
inline int inline_func2() {
return non_inline_func();
}
static int non_inline_func()
{
return 2;
}
int public_func2()
{
return inline_func2();
}
主要来源:
#include "pch.h"
int public_func1();
int public_func2();
void TestInline()
{
int i =public_func1();
int j= public_func2();
}
结果是 i=j=1。内联函数的定义在这里是一样的。这应该违反这个:https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule
从每个定义中查找名称会找到相同的实体(之后 重载决议)
【问题讨论】:
-
source1和source2中inline_func的定义不同,应该会有错误 这会导致Undefined Behavior。如果我是对的,这违反了 ODR。另一个问题是标准是否要求诊断...
-
在cppreference.com 找到:程序中可能有多个内联函数或变量的定义(C++17 起),只要每个定义出现在不同的翻译中单元和(对于非静态内联函数和变量(C++17 起))所有定义都是相同的。 和 如果定义了具有外部链接的内联函数或变量(C++17 起)在不同的翻译单元中不同,行为是未定义的。没有提到诊断(或者我忽略了它)。
-
第一句的结尾,“通常 [...]”,是作者的臆想。
-
“应该有错误”当然,你已经做到了。
-
@molbdnilo 到目前为止我还没有看到反例,你呢?
标签: c++ visual-studio language-lawyer inline msvc14