c++language-lawyerc++23one-definition-rule

Does C++23 allow multiple definitions of a namespace-scope non-inline variable in different translation units?


In old versions of C++, such as C++17, the one-definition rule was intuitive at a high-level in that it allowed only one definition of variables

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement;

But this prohibition has been removed.

Paragraph 14 does include restrictions that "For any definable item D with definitions in multiple translation units, if D is a non-inline non-templated function or variable..." essentially the definitions have to be identical. But that seems to imply it is indeed possible to have a program like:

// a.cc
int a = 1;

// b.cc
int a = 1;

Did the ODR rule indeed get heavily relaxed for non-inline variables? If so, why? If not, what is the new normative language prohibiting such multiple definitions?


Solution

  • Here is a more complete quote from [basic.def.odr] (C++23)

    For any definable item D with definitions in multiple translation units,

    • if D is a non-inline non-templated function or variable, or
    • if the definitions in different translation units do not satisfy the following requirements,

    the program is ill-formed;

    This rule has not changed.

    For any definition in multiple translation units:

    That makes your code example an ODR violation in C++23.