Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2024-12-22 15:45:29


Ruben Perez wrote:
> > By the way, I posted about the optional `export` idea to the committee
> > mailing list, and Michael Spencer replied and basically said "don't".
> >
> > "My suggestion is to do either `export import <boost/foo.hpp>;` in the
> > module if you are ok with getting extra declarations, or `export using ...` like
> libc++ does.
> > Trying to textually include a header into the purview of a named
> > module is fraught with issues."
> >
> > Since everything that's textually included becomes attached to the
> > named module, it's too easy to create ODR violations.
> >
> > But, apparently, Clang doesn't like header units, so the above is also
> > not quite optimal.
>
> I'd like to understand more about this, since this is the approach I have been
> following (and AFAIK, the one that John Maddock and Matt Borland followed,
> too). What would be the possible ODR violations here? Does he refer to the
> case where we forget to #ifdef-out an include for a dependency?

Yes. Assume for a moment that we don't have `import std;` available. In that
case, an #include <algorithm> from one of our headers would attach all its
declarations and definitions to our named module. When a user imports our
module and includes <algorithm>, that's an ODR violation.

The way to avoid this is to include <algorithm>, along with everything else,
in the GMF of our named module, so that the includes inside the module
become no-ops. But we could easily miss such an include.

This would also apply to Boost libraries that aren't modules, such as Config.

This problem seems to make modules an all or nothing proposition. If one
Boost library is a module, everything else also must be. We can't really mix
and match modules and includes on a per-library basis as I envisaged. And
things would be simplified considerably if we can also extend this to the
standard library. It's either both import boost.* and import std, or neither.

> It looks like `export import <boost/foo.hpp>;` could be done easily by users (if
> it worked).

At the source level yes, but not on the CMake level.

> At the minute, `export using` has problems:
> 1) It doesn't work properly under MSVC because of an apparent language bug
> regarding specializations [2] [3].
> 2) It ends up placing *a lot* of declarations in the global module fragment.
> clang docs suggest to avoid this [1], and I recall someone on the ML argued in
> this direction, too, but I can't find the relevant message.

IIUC, this is still better for performance than mixing named modules and
includes, even if the extern "C++" trick is used to avoid the ODR violations.
And I'm not sure that we can realistically avoid mixing imports and includes.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk