Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the one definition rule abandoned for C++17?

Citing C++ Draft N4713:

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 (9.4.1); no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 15.1, 15.4 and 15.8). An inline function or variable shall be defined in every translation unit in which it is odr-used outside of a discarded statement.

In C++ versions prior to C++17, I can get around this restriction by just declaring my functions inline. C++17 adds the same feature for variables.

Furthermore, it seems to me that the inline-Keyword does not serve another purpose apart from making it possible to ignore the ODR.

So, why isn't this whole rule just abandoned for C++17 ? I can't see the purpose of a rule that can be turned off.

like image 635
Ricardo Avatar asked Feb 08 '19 14:02

Ricardo


2 Answers

"Turning off" the ODR with inline is not free: the definition of an inline entity must be present in every translation unit. Note that this implies that any change to its definition causes re-compilation of every compilation unit that uses it. This would be particularly unpleasant when the function is part of some library many / big projects depend upon.

Non-inline functions, on the other hand, live in just one compilation unit and are referenced via some symbol by the linker when needed elsewhere. Complying with the ODR guarantees that symbol is not ambiguous.

like image 176
Baum mit Augen Avatar answered Sep 28 '22 00:09

Baum mit Augen


inline is dangerous and expensive.

It is expensive because every compilation unit that uses something now depends on the definition of the thing. So change the body? Recompile every user of it.

It is dangerous because if two inline definitions disagree, your program is IF-NDR (ill formed, no diagnostic required).

Without inline, two definitions cause an ill formed program, but the compiler must provide a diagnostic; usually a hard error.

inline turns off that extremely useful warning.

If every compiler was capable of converting the IF-NDR of different inline definitions into a diagnostic error message you'd have more of a case. So long as that proves difficult and/or not implemented, inline is a "activate unsafe mode!" option. Making it default would be counter productive.

like image 20
Yakk - Adam Nevraumont Avatar answered Sep 27 '22 23:09

Yakk - Adam Nevraumont