VS2019中内联函数的几个问题 我在VS2019:中对C++内联函数做了一些可能的实验。

VS2019中内联函数的几个问题 我在VS2019:中对C++内联函数做了一些可能的实验。,c++,visual-studio,language-lawyer,inline,msvc14,C++,Visual Studio,Language Lawyer,Inline,Msvc14,资料来源1: #include "pch.h" inline int inline_func(int i) { return i; } void testinline1() { inline_func(0); } #include "pch.h" int non_inline_func(); inline int inline_func2() { return non_inline_func(); } static int non_inline_func()

资料来源1:

#include "pch.h"

inline int inline_func(int i) {
    return  i;
}

void testinline1()
{
    inline_func(0);
}
#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"

inline int inline_func(int i) {
    return  i*i ;
}

void testinline2()
{
    inline_func(0);
}
#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"

inline int inline_func(int i);
int main(int argc,char* argv[])
{   
    int i = inline_func(2);
}
#include "pch.h"

int public_func1();
int public_func2();

void TestInline()
{
    int i =public_func1();
    int j= public_func2();
}
根据第节内联函数的存储类

C++中,如果需要,定义内联函数将发出函数 在翻译单元之间共享,通常通过将其放入 需要它的对象文件的公共部分。功能 在任何地方都必须具有相同的定义,始终使用内联 限定词

source1和source2中inline_func的定义不同,因此应该存在错误,但VS2019中没有此类错误

main中的i的结果是2,它来自source1中的inline_func,这似乎是构建过程的随机选择,因为如果我在source1中注释testinline 1,那么我将变成4,因为source1中的inline_func不会显示在对象文件中,而不会在同一个源中使用。当我在source2中对testinline2进行注释时,内联函数也会出现未定义的符号错误

为什么会发生这种情况?这是C++不覆盖还是只有MSVC不覆盖?< /P> 答复后更新:

下面是一个更好的例子:

资料来源1:

#include "pch.h"

inline int inline_func(int i) {
    return  i;
}

void testinline1()
{
    inline_func(0);
}
#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"

inline int inline_func(int i) {
    return  i*i ;
}

void testinline2()
{
    inline_func(0);
}
#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"

inline int inline_func(int i);
int main(int argc,char* argv[])
{   
    int i = inline_func(2);
}
#include "pch.h"

int public_func1();
int public_func2();

void TestInline()
{
    int i =public_func1();
    int j= public_func2();
}
结果是i=j=1。内联函数的定义在这里是相同的。这应违反以下规定:

从每个定义中进行名称查找后会查找相同的实体 过载分辨率

发件人:

如果满足所有这些要求,程序的行为就好像整个程序中只有一个定义一样。否则,程序格式不正确,无需诊断

[我的重点]

如果由于两个定义不相同而导致ODR冲突,则编译器不必发出警告或错误消息。

来自:

如果满足所有这些要求,程序的行为就好像整个程序中只有一个定义一样。否则,程序格式不正确,无需诊断

[我的重点]


如果你有一个ODR违反,因为这两个定义不相同,编译器不必发出警告或错误消息。

< P>有趣的是,在MSVS2019中ISO C++ 14……/P> 内联函数:

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");
}
不在线。它总是导致编译器发出调用:/

当我:

使用std::cout。。。像个好孩子; 直接调用函数丢弃或删除; 直接使用返回值调用函数 以及不论是否:

传递的参数为立即/文字 传递的参数是堆栈局部变量 传递的参数是堆分配的静态全局参数
函数变为UTI32 32 t fUTAL {返回1;} P>有趣的是,在MSVS2019中,ISO C++ 14……/P> 内联函数:

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");
}
不在线。它总是导致编译器发出调用:/

当我:

使用std::cout。。。像个好孩子; 直接调用函数丢弃或删除; 直接使用返回值调用函数 以及不论是否:

传递的参数为立即/文字 传递的参数是堆栈局部变量 传递的参数是堆分配的静态全局参数
函数更改为uint32_t fvoid{return 1;}source1和source2中的inline_func的定义不同,因此应该存在错误,这将导致未定义的行为。如果我是对的,这违反了ODR。另一个问题是,标准是否要求进行诊断……发现于:自C++17以来,程序中可能有多个内联函数或变量定义,只要每个定义出现在不同的转换单元中,对于非静态内联函数和变量,自C++17以来,所有定义都是相同的。如果自C++17以来,具有外部链接的内联函数或变量在不同的转换单元中定义不同,则行为是未定义的。诊断没有提到或我忽略了它。第一句话的结尾,通常是[…],是作者虚构的。肯定有错误,你犯了一个。@molbdnilo我到目前为止还没有看到反例,是吗?source1和source2中的inline_func的定义不同,因此应该存在错误,这将导致未定义的行为。如果我是对的,这违反了ODR。另一个问题是,标准是否要求进行诊断……发现于:自C++17以来,程序中可能有多个内联函数或变量定义,只要每个定义出现在不同的转换单元中,对于非静态内联函数和变量,自C++17以来,所有定义都是相同的。如果自C++17以来,具有外部链接的内联函数或变量在不同的转换单元中定义不同,则行为是未定义的。未提及诊断或I o
我看了看。第一句的结尾,通常是[…],是作者虚构的。肯定有错误,你犯了一个。@molbdnilo我到目前为止还没有看到反例,是吗?这是否意味着在头文件中的内联函数中使用if和宏是不好的,除非在使用该头文件的任何潜在源中预处理结果确保相同?@jw_uuu是的,这可能是不好的。这是否意味着在头文件中的内联函数中使用if和宏是不好的,除非预处理结果相同在使用该标题的任何潜在源中是否确实相同?@jw_uuu是,这可能很糟糕。