c++visual-studiolanguage-lawyerinlinemsvc14

Some problem about inline function in VS2019


I'm doing some (maybe exotic) experiments about C++ inline functions in VS2019:

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);
}

main source:

#include "pch.h"

inline int inline_func(int i);
int main(int argc,char* argv[])
{   
    int i = inline_func(2);
}

According to "Storage classes of inline functions" section of http://en.wikipedia.org/wiki/Inline_function,

In C++, a function defined inline will, if required, emit a function shared among translation units, typically by putting it into the common section of the object file for which it is needed. The function must have the same definition everywhere, always with the inline qualifier.

The definitions of inline_func in source1 and source2 is different so there should be errors, but there is no such error in VS2019.

The result of i in main() is 2 which is from the inline_func in source1, this seems to be a random choice by the building process since if I comment testinline1 in source1, then i will become 4 since the inline_func in source1 won't show up in the object file without being used in the same source. When I comment testinline2 in source2 too there will be undefined symbol error for inline_func as expected.

Why does these happen? Is this where C++ doesn't cover or only MSVC doesn't cover?

Updated after answered:

Here is a better example:

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();
}

main source:

#include "pch.h"

int public_func1();
int public_func2();

void TestInline()
{
    int i =public_func1();
    int j= public_func2();
}

The result is i=j=1. The definition of the inline functions are the same here. This should violate this: https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule

name lookup from within each definition finds the same entities (after overload-resolution)


Solution

  • From this One Definition Rule (ODR) reference:

    If all these requirements are satisfied, the program behaves as if there is only one definition in the entire program. Otherwise, the program is ill-formed, no diagnostic required.

    [Emphasis mine]

    If you have an ODR-violation (which you have since the two definitions are not identical) the compiler doesn't have to emit a warning or error message.