Submodule semantics with macro guard

Richard Smith via cfe-commits cfe-commits at
Mon Sep 19 22:58:24 PDT 2016

On 19 Sep 2016 6:53 pm, "Manman via cfe-commits" <cfe-commits at>

On Sep 19, 2016, at 5:55 PM, Richard Smith via cfe-commits <
cfe-commits at> wrote:

Your c.h is not correct. It would introduce a definition of c in every file
where it's included, so it's not a modular header.

Hi Richard,

What do you mean by c.h is not correct? It is guarded by a macro, so if we
are not using modules, it will work.

It will not work (due to multiple definition errors) if it's included into
two source files anywhere in the entire program.

If it's only intended to be included into a single source file in the
entire program, there's no point in putting it in a module.

Also I thought the definition of a non-modular header is that it is not
mapped to any module. Is that my misunderstanding? Is there a formal
definition for modular header?

I'm not sure if we have this written down anywhere, but it's something
like: a header that is self contained, does not intended to depend on the
compilation state at its point of inclusion, and has no effect other than
making some set of declarations and macros visible.


On 19 Sep 2016 5:21 pm, "Manman via cfe-commits" <cfe-commits at>

> Hi Richard & Ben,
> Given a simple testing case, where we have two submodules X.A (A.h) and
> X.B (B.h, it includes C.h, and C.h is guarded with a macro), when we import
> X.A and then textually include a header C.h, we get redefinition error.
> This is because the macro guard is owned by module X.B that is not yet
> visible. I wonder what the fix is if this is considered a compiler issue.
> We can:
> 1> do not emit the redefinition error if the earlier definition is not
> visible, or
> 2> emit diagnostics to suggest user to import the whole module, when
> redefinition happens because the module includes a non-modular header and
> the non-modular header is also textually included, or
> 3> other suggestions?
> Note that if we textually include C.h, then import X.A, there are no
> compiler errors.
> The testing case here:
> clang -cc1 repro.c -fsyntax-only -I Inputs4/ -fmodules
> -fimplicit-module-maps -fmodules-cache-path=tmp
> cat repro.c
> #include "A.h" //modular header
> #include "C.h" //non-modular header
> cat Inputs4/
> module X {
>   module A {
>     header "A.h"
>     export *
>   }
>   module B {
>     header "B.h"
>     export *
>   }
>   export *
> }
> cat Inputs4/A.h
> #ifndef __A_h__
> #define __A_h__
> #endif
> cat Inputs4/B.h
> #ifndef __B_h__
> #define __B_h__
> #include "C.h"
> #endif
> cat Inputs4/C.h
> #ifndef __C_h__
> #define __C_h__
> int c = 1;
> const int d = 2;
> #endif
> Thanks,
> Manman
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at
cfe-commits mailing list
cfe-commits at

cfe-commits mailing list
cfe-commits at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the cfe-commits mailing list