Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do C++ modules make ODR violations absent?

From the N4720 C++ Modules draft, [basic.def.odr]/6 says:

[…] For an entity with an exported declaration, there shall be only one definition of that entity; a diagnostic is required only if the abstract semantics graph of the module contains a definition of the entity. [Note: If the definition is not in the interface unit, then at most one module unit can have and make use of the definition. — end note] […]

Which, as per my understanding, practically gives templates a chance to be parsed only once by the compiler, contrasting to the current state of affairs (having an exact copy of their definitions per translation unit). This is also valid for other entities with similar case, such as inline functions/variables.

My question arised from the fact that, as you can only have at most one definition of entities (as described in [basic.def.odr]/1) per translation unit, it is undefined behavior to have differing definitions of an entity across TUs. And, as exported entities shall have only one definition across the entire compilation unit (making unexported ones unique to their implementation unit), getting the definition wrong, from my perspective, is harder if not impossible.

Finally, to put it simply: will (or does, or should) the utilization of modules make it impossible to violate ODR rules, or otherwise harder to get wrong?

like image 882
Mário Feroldi Avatar asked Feb 07 '18 14:02

Mário Feroldi


People also ask

Is it possible to write code like this without strong module ownership?

In practice and in general, one wouldn’t write code purposefully like that, but it is hard to avoid in practice under code migration, evolution, and maintenance. Before strong module ownership semantics, a program such as this would not be possible (with two external linkage names of munge ). Strong ownership buys this new odr guarantee.

Should I imply C++ modules under/STD:C++latest?

There are a few caveats to implying C++ Modules under /std:c++latest: /std:c++latest now implies /permissive-. This means that customers currently relying on the permissive behavior of the compiler in combination with /std:c++latest are required to now apply /permissive on the command line.

How do I continue using the standard library of C++ modules?

To continue using the standard library Modules users will need /experimental:module as part of their command line options. C++20 added a new section to a primary Module interface known as the private Module fragment, [module.private.frag].

Why do we need a module system for C++?

There is a great paper “A Module System for C++” which details rationale behind strong ownership. Quite possibly the most essential part of using C++ Modules is having a build system which can cope with the requirements of C++ Modules build while providing an experience for users without a steep learning curve.


1 Answers

If a project is fully modularized (that is, never uses #include), then most accidental ODR violations would go away. Most accidental ODR violations happen due to the nature of #include: including a global variable with a definition and so forth. Or two-phase template lookup issues, where two files include the same template, but because of what each included before that template, the definition of the two templates is different.

However, this does nothing to prevent less "accidental" ODR violations. Because "same entity" is defined by its name, and the name of an entity has nothing to do with the module it was exported from, two modules can provide different definitions of the same entity. So basically, name collisions.

This only becomes a compile-error (ie: diagnostic required) if a single translation unit imports both such modules. If two separate translation units each include one of the modules with different definitions, then the program as a whole still violates ODR, but there doesn't have to be a diagnostic about it.

So even in a fully modularized codebase, ODR can still be violated.

like image 186
Nicol Bolas Avatar answered Oct 23 '22 03:10

Nicol Bolas