我正在做一些关于VS2019中C ++内联函数的实验(也许是外来的):
source1:
#include "pch.h"
inline int inline_func(int i) {
return i;
}
void testinline1()
{
inline_func(0);
}
source2:
#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,则由于source1中的inline_func,我将变成4如果未在同一源中使用,则不会显示在目标文件中。当我在source2中评论testinline2时,也会按预期出现inline_func的未定义符号错误。
为什么会这样?这是C ++不能覆盖的地方,还是MSVC不能覆盖的地方吗?
回答后更新:
这是一个更好的例子:
source1:
#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();
}
source2:
#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
在每个定义中的名称查找会找到相同的实体( 超载分辨率)
答案 0 :(得分:4)
来自this One Definition Rule (ODR) reference:
如果满足所有这些要求,则程序的行为就好像整个程序中只有一个定义。否则,程序格式错误,无需诊断。
[重点突出]
如果您有违反ODR的行为(由于两个定义不相同,您就有此行为),则编译器不必发出警告或错误消息。
答案 1 :(得分:0)
有趣的是,在 MSVS2019 ISO C++ 14 中...
内联函数:
inline uint32_t hanoi(int a) { __asm bsf eax, a } // Solve arbitrary 'Tower of Hanoi' round
调用:
int numMoves = (1<<numDisks)-1; /* Calculate number of moves needed to solve */
// Print full Tower Of Hanoi solution
for (int i = 1;i < numMoves;i++) {
printf("move disk %u %s\n", hanoi(i), hanoi(i) & 1 ? "left" : "right");
}
或者,只是:
hanoi(1);
不内联。它总是导致编译器发出 "Call" ://p>
和我一样:
并且不管是否:
uint32_t f(void) { return 1; }
<--让我吃惊!我注意到人们比我抱怨 VS2015 和 VS2017 中的类似内联问题更聪明 - 每个人都将其与 CLANG 和 GCC 中的相同代码进行比较,其编译器似乎没有任何问题:/每次 MS似乎已将其确定为编译器问题。
TBH,当涉及到内联函数时,VS 看起来可能有点“脆弱”:(
只是我的 2c
\o/ - “不要开枪!”