Date: Wed, 11 Apr 2018 07:30:53 +0200
Jens Maurer <Jens.Maurer_at_[hidden]> writes:
> On 04/09/2018 06:29 PM, Boris Kolpackov wrote:
>
> > To summarize my understanding: in this proposal (but not in Modules TS)
> > all import declarations must come first, before any other declarations.
>
> (The Modules TS does not allow exporting macros from modules at all.)
Yes, but it doesn't require all import declarations to come at the start
of the translation unit. And import declarations in/out of module
purview have different semantics in the module interface unit. So in
my view this is just one of the artificial restrictions of the Atom
proposal.
> > To me, personally, this feels like a bunch of artificial restrictions
> > to make something inherently broken kinda work.
>
> The subdivision of C++ translation unit text into a "module import header"
> and the rest, with different rules applied, certainly is a departure from
> current preprocessor style and C++ practice.
An even bigger departure, IMO, is having a preprocessor directive (import)
not starting with '#'.
> The question is: Would this approach address your build system concerns?
Theoretically -- yes. Practically -- hard to say since all the implications
will only become apparent once you start implementing it. But I think it's
pretty clear this will be a complex beast.
Of the top of my head I see two immediate issues:
1. The module dependency extraction will have to be supported by the
compilers since the semantics will have to be something like:
"Preprocess the import region and stop (we have to stop since
continuing preprocessing requires BMIs). Then parse the import
declarations and return the set of imported module names."
In fact, I don't even know if this can be implemented. Consider
this example:
import foo; // Exports FOO.
#ifndef FOO
# error foo
#endif
How does the compiler know where the import region ends? The first
non-import declaration won't work as this example shows (we are
using the exported macro FOO which means we need the BMI). Something
hackish like "first non-import declaration or first mentioning of
an exported macro"? But then how do we know FOO is an exported
macro without loading the BMI?
In contrast, for Modules TS we were able to implement this with
zero support from the compilers since we could simply preprocess
the entire translation unit and then shallow-parse module-related
declarations.
2. If one wants to provide proper (as in, part of the main build
phase) support for auto-generated headers (and we do in build2),
then we will need to extract header dependencies twice, first
time for the import region only and the second time for the
entire translation unit. Here is an example that illustrates
the problem:
#include "config.h" // Auto-generated, defines TARGET_*.
#ifdef TARGET_WINDOWS
import support.windows;
#else
import support.unix;
#endif
So, again, we will need support from the compiler for this
(something like -M -fonly-for-import-region).
Also, it is not clear why we need to endure all this complexity. The
C++ community (our target audience) is pretty clear it doesn't want
modules dragged into the preprocessor (here is one example[1] but
there are threads like this every time modules are discussed). We
ourselves definitely don't need it either. So perhaps the compromise
could be to make macro exporting optional, for example, via the #import
directive (for macro-exporting modules) and the import declaration (for
the rest of us) with the former expanded into the latter (by the
preprocessor)?
[1]
Here is the whole thread:
https://www.reddit.com/r/cpp/comments/854mu9/2018_jacksonville_iso_c_committee_reddit_trip/dvuqz0d/
Or see this fairly representative (and thoughtful) comment for TL;DR:
https://www.reddit.com/r/cpp/comments/854mu9/2018_jacksonville_iso_c_committee_reddit_trip/dvuy0i2/
Boris
> On 04/09/2018 06:29 PM, Boris Kolpackov wrote:
>
> > To summarize my understanding: in this proposal (but not in Modules TS)
> > all import declarations must come first, before any other declarations.
>
> (The Modules TS does not allow exporting macros from modules at all.)
Yes, but it doesn't require all import declarations to come at the start
of the translation unit. And import declarations in/out of module
purview have different semantics in the module interface unit. So in
my view this is just one of the artificial restrictions of the Atom
proposal.
> > To me, personally, this feels like a bunch of artificial restrictions
> > to make something inherently broken kinda work.
>
> The subdivision of C++ translation unit text into a "module import header"
> and the rest, with different rules applied, certainly is a departure from
> current preprocessor style and C++ practice.
An even bigger departure, IMO, is having a preprocessor directive (import)
not starting with '#'.
> The question is: Would this approach address your build system concerns?
Theoretically -- yes. Practically -- hard to say since all the implications
will only become apparent once you start implementing it. But I think it's
pretty clear this will be a complex beast.
Of the top of my head I see two immediate issues:
1. The module dependency extraction will have to be supported by the
compilers since the semantics will have to be something like:
"Preprocess the import region and stop (we have to stop since
continuing preprocessing requires BMIs). Then parse the import
declarations and return the set of imported module names."
In fact, I don't even know if this can be implemented. Consider
this example:
import foo; // Exports FOO.
#ifndef FOO
# error foo
#endif
How does the compiler know where the import region ends? The first
non-import declaration won't work as this example shows (we are
using the exported macro FOO which means we need the BMI). Something
hackish like "first non-import declaration or first mentioning of
an exported macro"? But then how do we know FOO is an exported
macro without loading the BMI?
In contrast, for Modules TS we were able to implement this with
zero support from the compilers since we could simply preprocess
the entire translation unit and then shallow-parse module-related
declarations.
2. If one wants to provide proper (as in, part of the main build
phase) support for auto-generated headers (and we do in build2),
then we will need to extract header dependencies twice, first
time for the import region only and the second time for the
entire translation unit. Here is an example that illustrates
the problem:
#include "config.h" // Auto-generated, defines TARGET_*.
#ifdef TARGET_WINDOWS
import support.windows;
#else
import support.unix;
#endif
So, again, we will need support from the compiler for this
(something like -M -fonly-for-import-region).
Also, it is not clear why we need to endure all this complexity. The
C++ community (our target audience) is pretty clear it doesn't want
modules dragged into the preprocessor (here is one example[1] but
there are threads like this every time modules are discussed). We
ourselves definitely don't need it either. So perhaps the compromise
could be to make macro exporting optional, for example, via the #import
directive (for macro-exporting modules) and the import declaration (for
the rest of us) with the former expanded into the latter (by the
preprocessor)?
[1]
Here is the whole thread:
https://www.reddit.com/r/cpp/comments/854mu9/2018_jacksonville_iso_c_committee_reddit_trip/dvuqz0d/
Or see this fairly representative (and thoughtful) comment for TL;DR:
https://www.reddit.com/r/cpp/comments/854mu9/2018_jacksonville_iso_c_committee_reddit_trip/dvuy0i2/
Boris
Received on 2018-04-11 07:31:03