[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