https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119215
--- Comment #23 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to James K. Lowden from comment #21) > If I wrap one of the two yysymbol_kind_t in a namespace, anonymous or not, > does that solve the problem? Yes. foo::yysymbol_kind_t and ::yysymbol_kind_t and <ANON>::yysymbol_kind_t would all be distinct types. > Would it be true then, that any two libraries in /usr/lib, if they are used > in the same program, must not use the same name for an enumerated type? Yes. That's what namespaces are for. > If > so, are they relying on UB that is exposed only under LTO? Yes. > Thank you for taking the time to patiently explain the issue. I tried to be > as concrete as possible so that you could see what I'm thinking. Your > concrete example and chapter-and-verse citing are helping me understand a > feature that contradicts everything I know about C++ names. I understand > how one enum, shared between two TUs using the same header file, needs to be > consistent across the program. I don't understand how two enums used > independently and not shared, can be confused by the compiler if they're not > exposed to the linker. It's a terrible predicament, but here we are. Using a header file has absolutely no effect on linkage. The compiler doesn't care whether you define enum foo in a header and include it in two source files, or define enum foo in two sources files. The effect is identical. Headers do not have magical scoping properties, they're effectively just copy & paste functionality. You are making up some magical property of "used independently and not shared" which has no basis in the language standard. If two TUs define 'enum kind_t' then you have two definitions, period. The solution is to not do that. Make one of them define foo::kind_t and the other one define bar::kind_t (where one or both of foo and bar could be an anon namespace instead, or one could be the global namespace, what matters is that foo and bar are not the *same* namespace).
