https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119983
--- Comment #5 from Nathaniel Shead <nshead at gcc dot gnu.org> --- (In reply to gap mman from comment #4) > (In reply to Nathaniel Shead from comment #2) > > Thanks for the report! As Andrew noted, the ICE is fixed for 14.3 by > > r14-10825-g01d3a974fe3474c37cd52b595c29dddafad954dc. > > > > The code is ill-formed, however: > > > > export module M; > > struct {} instance; > > > > is not legal in a module interface, because of > > https://eel.is/c++draft/basic.link#15.2 (the type of the unnamed struct is > > TU-local), https://eel.is/c++draft/basic.link#14 (the declaration of the > > variable exposes the TU-local type), and > > https://eel.is/c++draft/basic.link#17 (the variable is not TU-local, so this > > is ill-formed). > > > > We don't check this in GCC 14 (so 14.3 will accept this code), but for GCC > > 15 we properly implement https://wg21.link/p1815 and so error in this case: > > > > <source>:2:11: error: 'instance' exposes TU-local entity 'struct<unnamed>' > > 2 | struct {} instance; > > | ^~~~~~~~ > > <source>:2:8: note: '<unnamed struct>' has no name and is not defined within > > a class, function, or initializer > > 2 | struct {} instance; > > | ^ > > Thank you for answering. I'm only using this variable within the TU. > > Am I correct in understanding the problem as the following: The instance, > even though not visible outside of the module, This is the issue: 'instance' *would* be visible outside of this TU, such as in e.g. a module implementation unit, but the unnamed struct would not be, which would cause issues. > doesn't have internal linkage > but names a TU local entity (the unnamed type), which causes exposure and is > therefore ill formed. To fix, either name the type to make it not TU local > or make the variable have internal linkage (adding `static` as in the > example). And yes, by adding 'static', or wrapping in an unnamed namespace, 'instance' would no longer be accessible in other TUs, so there's no reason to complain anymore. > > As for a fix in current GCC14.2 I'm using, my only bet is naming this type? Naming the type is probably the most straight-forward workaround, yes. > I'm actually declaring it `constexpr`(which, unfortunately, is explicitly > defined as exposure) > ``` > constexpr struct > { > void aRandomFunc() > { > > } > } variableWithNamelessType{}; > ``` > > I also noticed something I didn't quite understand in GCC14.2. If I declare > this as `static constexpr` and use it in an exported function, then I'm > fine; but if the function is templatized, then I get "references internal > linkage entity". https://godbolt.org/z/3rKn3v7rq In GCC 15 both works, which > I believe should be the correct behavior? Within a non-inline templated function it's actually still problematic, but only if an importer attempts to instantiate it; this is the behaviour mandated by the standard. You can experiment with '-Wtemplate-names-tu-local' (also enabled by '-Wextra') to see more. For a non-inline non-template function it's OK because we don't emit the bodies of such functions, so the entity is not exposed.