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?
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.