C++ Logo

sg15

Advanced search

Re: [SG15] [isocpp-modules] Determining identity like #pragma once

From: Tom Honermann <tom_at_[hidden]>
Date: Thu, 11 Jul 2019 16:26:46 -0400
On 7/10/19 6:40 PM, Richard Smith via Modules wrote:
> On Wed, Jul 10, 2019 at 3:15 PM Michael Spencer <bigcheesegs_at_[hidden]
> <mailto:bigcheesegs_at_[hidden]>> wrote:
>
> On Wed, Jul 10, 2019 at 2:51 PM Gabriel Dos Reis via SG15
> <sg15_at_[hidden] <mailto:sg15_at_[hidden]>> wrote:
>
>
>
> | -----Original Message-----
> | From: Bryce Adelstein Lelbach aka wash
> <brycelelbach_at_[hidden] <mailto:brycelelbach_at_[hidden]>>
> | Sent: Wednesday, July 10, 2019 2:37 PM
> | To: Gabriel Dos Reis <gdr_at_[hidden]
> <mailto:gdr_at_[hidden]>>
> | Cc: Tom Honermann <tom_at_[hidden]
> <mailto:tom_at_[hidden]>>; modules_at_[hidden]
> <mailto:modules_at_[hidden]>;
> | sg15_at_[hidden] <mailto:sg15_at_[hidden]>
> | Subject: Re: [isocpp-modules] [SG15] Determining identity
> like #pragma once
> |
> | On Wed, Jul 10, 2019 at 11:02 AM Gabriel Dos Reis
> <gdr_at_[hidden] <mailto:gdr_at_[hidden]>>
> | wrote:
> | >
> | > You are implying that the include translation is
> mandatory. Is that your
> | argument?
> |
> | It is my belief that include translation is mandatory.
> |
> | "If the header identified by the header-name denotes an
> importable
> | header ([module.import]), the preprocessing directive is instead
> | replaced by the preprocessing-tokens: import header-name ;"
> |
> https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Feel.is
> | %2Fc%2B%2Bdraft%2Fcpp.include%237&amp;data=02%7C01%7Cgdr%40mic
> | rosoft.com
> <http://rosoft.com>%7C57adb75b608743ebf6e208d7057ed5d4%7C72f988bf86f141af
> | 91ab2d7cd011db47%7C1%7C0%7C636983914618863287&amp;sdata=JsvGf
> | 0RfvcjOSMF6q%2FfsW60hhKx5TI%2F1K42M8PdRbOU%3D&amp;reserved=0
> |
> | To me, that reads as "including an importable header must be
> | translated to an import".
> |
> | Was that the original design intent?
>
> The original intent, as I understood it, was to *permit*
> include translation.
>
> A mandatory include translation is practically unworkable for
> the MSVC audience. I wouldn't be surprised at all if that is
> the case of other compilers too.
>
> A permission, as opposed to a requirement, would allow
> adoption of header import as better and principled replacement
> of PCH. Otherwise, it would create more problems than it solves.
>
> -- Gaby
>
>
> I was there for most of the LEWG discussion on D1502R0 (Standard
> library header units for C++20), and I can not say with confidence
> that the room understood the implication that this would require
> include translation. There don't seem to be any minutes of the
> discussion on the wiki.
>
> However, the paper does explicitly point this out:
>
> > This has a number of consequences, such as:
> > * ...
> > * Existing #includes of standard library headers transparently
> turn into module imports in C++20
>
> It also in the wording explicitly adds the headers to the set of
> implementation-defined importable headers.
>
> > An importable header is a member of an implementation-defined
> set of headers that includes all importable C++ library headers
> (16.5.1.2 [headers])
>
> So I believe the author's intent was to require that include
> translation occurs.
>
> + Richard so we can ask them :)
>
>
> Yes, my intent was to (effectively) require include translation for
> these parts of the standard library. In practice, an implementation
> could satisfy that requirement by instead providing standard library
> wrapper headers that simply contain a relevant import declaration --
> this does not strictly require an implementation to actually do
> include translation during preprocessing.
>
> An implementation that doesn't actually do include translation at all
> is still permissible using this technique. Such an implementation
> would need to document that its implementation-defined set of
> importable headers is empty other than the standard library headers.
> If they did so, then any "import header-name;" construct that didn't
> name a standard library header would violate [module.import]/5's "H
> shall identify an importable header." Such an implementation could
> still choose to accept such an import as a language extension. I would
> not encourage such an approach, but I think it's consistent with the
> wording we have.
>
> If we want to permit "import header-name;" without requiring include
> translation, and we want to allow re-exporting of imported header
> units, we'll need to fix the robustness issues that arise when a
> legacy header's macros (particularly include guards) are divorced from
> its semantic contents. (Nathan pointed this out during prior EWG
> discussion, and this non-robustness is the reason we require include
> translation for importable headers.) For example:
>
> // foo.h
> #fndef FOO_H
> #define FOO_H
> struct X {};
> #endif
>
> // TU A
> export module M;
> export import "foo.h";
>
> // TU B
> import M;
> // suppose we make a language change that allows this #include to be
> textually included rather than subject to include translation
> // then because the FOO_H macro is not visible here (because modules
> can't export macros), we get...
> #include "foo.h" // error, redefinition of X
>
> The same issue arises with the global module fragment:
>
> // TU C
> module;
> #include "foo.h"
> export module M;
> export X f(); // definition of X is reachable through this TU
>
> // TU D
> import M;
> #include "foo.h" // error, redefinition of X
>
> I think there's a reasonable fix to both of these; instead of
> rejecting a redefinition when a prior definition is reachable, we
> should only reject a redefinition of an entity attached to the global
> module when there's a prior definition in the same translation unit.
> The ODR would apply as normal to such global-module-owned
> redefinitions. (I think I've suggested this on either the evolution or
> modules reflector before.)

For the purposes of reflection (e.g., get_source_line), which definition
would win? The in-this-TU one? Or would there be a requirement that
the presumed source location for each definition match in order to avoid
an ODR issue? (I've not followed the reflection work closely; for all I
know, this is already specified for the general case of multiple
declarations).

Tom.

>
> If we make that change, both the global module fragment and header
> units would become more robust, and we would no longer need to require
> include translation for all importable headers. (I think we should
> still require include translation for the standard library, though as
> noted above, an implementation can model that by providing header
> files that contain imports.)
>
> _______________________________________________
> Modules mailing list
> Modules_at_[hidden]
> Subscription: http://lists.isocpp.org/mailman/listinfo.cgi/modules
> Link to this post: http://lists.isocpp.org/modules/2019/07/0513.php



Received on 2019-07-11 15:28:42