C++ Logo


Advanced search

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

From: Gabriel Dos Reis <gdr_at_[hidden]>
Date: Wed, 10 Jul 2019 17:00:50 +0000

> On Jul 10, 2019, at 6:27 AM, Bryce Adelstein Lelbach aka wash <brycelelbach_at_gmail.com> wrote:
> On Wed, Jul 10, 2019 at 2:48 AM Gabriel Dos Reis via SG15
> <sg15_at_lists.isocpp.org> wrote:
>> Also, we should note that import and #include of the same file can lead to unexpected results, so we need both clarifications and recommendations there for users.
> Why should this lead to unexpected results?
> Suppose I have:
> #include <foo>
> import <foo>;

To illustrate the concern, let me further add that the header <foo> has include guard and all that.

The #include copy-n-pastes the content of foo in the current translation - including of course any definitions. The import makes available any declaration/definition from the translation unit of foo. The program ends up with multiple definitions (at link time at least).

Now, consider your example written in the reverse order:

   import <foo>;
   #include <foo>

Just as before, the import makes available the content of foo, including the include guard macro for foo. The #include sees that include guard and just skips inclusion. The program ends up with just (at most) one definition.

User says “Woah!”.

Now, these import and include way actually be brought into the current TU via different header files (say one being modern and the other on the old regimen). User mystified.

Note, there is no include-translation involved.
Note^2: with existing include mechanism, the include guard makes the inclusion idempotent.

— Gaby

> https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Feel.is%2Fc%2B%2Bdraft%2Fcpp.include%237&amp;data=02%7C01%7Cgdr%40microsoft.com%7C6bec032805284ad23cc108d7053a4be6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636983620251783428&amp;sdata=kE4nGNCXFHtkhPawj1TUlgU7N%2FA2TNZHputz2F1DlvY%3D&amp;reserved=0 says "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%2Fmodule.import%235&amp;data=02%7C01%7Cgdr%40microsoft.com%7C6bec032805284ad23cc108d7053a4be6%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636983620251793433&amp;sdata=qZlinqSgeHF8T%2F6FlrTQDOSGDUavMPj3DSiV3c66Bbo%3D&amp;reserved=0 says "A
> module-import-declaration that specifies a header-name H imports a
> synthesized header unit ..." and later "H shall identify an importable
> header." (I can't tell if this is a requirement on the user or the
> implementation - e.g. is this saying that this is ill-formed if H is
> not what the implementation considers to be an importable header).
> Anyways, in the above example, import <foo>; (if it's well-formed)
> means that foo is an importable header. This means that the #include
> <foo> is [cpp.include] p7 replaced with an import <foo>;. I don't see
> anything unexpected about importing a module a twice?
> Am I missing something?
> --
> Bryce Adelstein Lelbach aka wash
> CUDA Core C++ Libraries Lead @ NVIDIA
> ISO C++ Library Evolution Incubator Chair
> ISO C++ Tooling Chair
> CppCon and C++Now Program Chair
> CUDA Convert and Reformed AVX Junkie
> Sleep is for the weak
> --

Received on 2019-07-10 12:02:45