[Bug c++/99931] New: Unnamed `struct` defined with `using` having internal linkage instead of external, unlike `typedef`, yielding different semantics for two

egor_suvorov at mail dot ru gcc-bugzilla@gcc.gnu.org
Tue Apr 6 10:42:32 GMT 2021


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99931

            Bug ID: 99931
           Summary: Unnamed `struct` defined with `using` having internal
                    linkage instead of external, unlike `typedef`,
                    yielding different semantics for two
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: egor_suvorov at mail dot ru
  Target Milestone: ---

Possible duplicate of this StackOverflow question:
https://stackoverflow.com/questions/48613758/using-vs-typedef-is-there-a-subtle-lesser-known-difference

Found through this StackOverflow question by Momme Sherif with help of M.M:
https://stackoverflow.com/questions/66966426/error-defining-an-unnamed-structure-in-c

Consider two following files:

// a.cpp
using Foo = struct {};
void test(Foo);
int main() {
    Foo f;
    test(f);
}
// b.cpp
using Foo = struct {};
void test(Foo) {
}

`g++ a.cpp b.cpp` fails on my machine with:

a.cpp:2:6: error: 'void test(Foo)', declared using unnamed type, is used but
never defined [-fpermissive]
    2 | void test(Foo);
      |      ^~~~
a.cpp:1:7: note: 'using Foo = struct<unnamed>' does not refer to the
unqualified type, so it is not used for linkage
    1 | using Foo = struct {};
      |       ^~~
a.cpp:2:6: warning: 'void test(Foo)' used but never defined
    2 | void test(Foo);
      |      ^~~~

However, if you change `using Foo = struct {};` to `typedef struct {} Foo;`,
the code will compile successfully.

Looks like a clear semantics difference between `typedef` and `using`, which
kind of contradicts [dcl.typedef]/2 (emphasis mine):

> A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword is not looked up; it becomes a typedef-name and the optional attribute-specifier-seq following the identifier appertains to that typedef-name. **Such a typedef-name has the same semantics as if it were introduced by the typedef specifier.** In particular, it does not define a new type.

My GCC is

g++ (Rev6, Built by MSYS2 project) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


More information about the Gcc-bugs mailing list