VS2019中C++内联函数违背ODR规则的行为及原因问询
Great question—these are classic examples of how One Definition Rule (ODR) violations lead to undefined behavior (UB), and it’s important to clarify how the C++ standard handles this, versus MSVC’s specific implementation choices.
Issue 1: Different inline function definitions across translation units (TUs) with no link errors and random results
First, let’s anchor this to the C++ standard:
An inline function or variable shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case.
When you define inline_func differently in two TUs, you’re violating this rule. The standard explicitly classifies this as undefined behavior—meaning compilers and linkers are under no obligation to detect the violation, and any outcome (link success, random runtime results, crashes, etc.) is permissible.
MSVC’s behavior here isn’t unique. Most mainstream compilers (GCC, Clang included) don’t perform cross-TU checks for inline function definition consistency by default—doing so would add significant overhead to the build process. The linker might pick one of the two definitions arbitrarily (hence the random results), or merge them in some way, but none of this is guaranteed.
Issue 2: Consistent inline function definitions, but differing static non-inline function calls leading to unexpected returns
Your second scenario also boils down to an ODR violation, but it’s a bit more subtle. The ODR doesn’t just require inline functions to have identical token sequences—it also mandates that name lookup within each definition resolves to the same entities.
In your case, inline_func2 calls a static non_inline_func in each TU. Static functions have internal linkage, so the non_inline_func in TU1 is a completely separate entity from the one in TU2. This means when inline_func2 is defined in each TU, the name lookup for non_inline_func finds a different function in each case—violating the ODR’s requirement for consistent entity resolution across all inline definitions.
Again, this is explicitly undefined behavior per the C++ standard. MSVC’s outcome (both public_func1 and public_func2 returning 1) is just one possible manifestation of UB. Other compilers might produce different results, but none of them are "wrong"—the standard gives no guarantees once you violate the ODR.
Key Takeaway
Neither of these scenarios are gaps in the C++ standard, nor are they MSVC-specific issues. They’re direct consequences of violating the ODR, which puts your program in the realm of undefined behavior. Compilers aren’t required to catch these violations, and their behavior can vary, but all outcomes are allowed by the standard.
内容的提问来源于stack exchange,提问作者jw_

