16

Is the following code legal?:

struct
{
    int  x;
};

This code simply defines an unnamed structure. I do not intend to create objects of this type, nor do I need this structure in any other way. It simply appears in the source as a side effect of some complex macro expansion.

Useless though it is, I see no problem with it. Just another piece of code that can be compiled and then optimized out completely.

However, in the real world the outcome is quite different from my expectations:

GCC 8.3 reports an error:

error: abstract declarator '<unnamed struct>' used as declaration

Clang 8.0.0 reports an error too:

error: anonymous structs and classes must be class members
warning: declaration does not declare anything [-Wmissing-declarations]

Only MSVC 2017 sees no problem with such source.

So, the question is: who's right? Is there a relevant quote from the Standard that explicitly forbids such declarations?

Edit:
The project uses C++11. But the error messages are the same for C++98, C++11 and C++17.

leetNightshade
  • 2,673
  • 2
  • 36
  • 47
Igor G
  • 1,838
  • 6
  • 18
  • 1
    According to https://stackoverflow.com/a/12785369/969365 C++ does not allow anonymous structs (but it says that C11 does, and that future revisions to C++ might add support). Note that there are differences between anonoymous structs and unnamed structs. – simon Apr 30 '19 at 07:54
  • http://www.cplusplus.com/forum/general/138733/ – Mayur Apr 30 '19 at 07:55
  • https://stackoverflow.com/questions/2253878/why-does-c-disallow-anonymous-structs – VLL Apr 30 '19 at 08:03
  • Microsoft's compiler has (and the Windows headers use) an utterly pointless thing called an anonymous struct. That's why it accepts that code. – Pete Becker Apr 30 '19 at 12:33
  • This question confuses anonymous and unnamed structs. The title is about unnamed structs, but your example is an anonymous struct. Anonymous structs are C only. Unnamed structs are valid C++. – leetNightshade Apr 26 '22 at 21:40

1 Answers1

15

No, it is not allowed. GCC and Clang are right.

Per [dcl.dcl]/3 (7 Declarations) in N3337 (C++11 final draft), a class declaration must introduce at one name to the program. For example, the following are invalid:

enum { };
typedef class { }; 

(Note: this isn't unique to C++11. In N4140 (C++14 final draft) it is [dcl.dcl]/5 (7 Declarations). In N4659 (C++17 final draft) it is [dcl.dcl]/5 (10 Declarations).)

L. F.
  • 19,445
  • 8
  • 48
  • 82
  • The question is tagged c++11, and the wording isn't there for N3337 – StoryTeller - Unslander Monica Apr 30 '19 at 08:05
  • 2
    @StoryTeller In N3337, it is [dcl.dcl]/3 – VLL Apr 30 '19 at 08:07
  • Yes, C++11 is my primary concern. However, error messages are the same whether I add compiler option `-std=c++11` or not. – Igor G Apr 30 '19 at 08:08
  • The important sentence in the clause is "the decl-specifier-seq shall introduce one or more names into the program, or shall redeclare a name introduced by a previous declaration". `struct{};` introduces no new names. – VLL Apr 30 '19 at 08:09
  • @IgorG As Ville-Valtteri has pointed out, it is the same for C++11. I will update my answer to reflect this. – L. F. Apr 30 '19 at 08:09
  • Well then. Quoting it into the answer and fixing the text reference would improve it for careless readers such as myself. But yeah, this is the correct paragraph, nailed it. – StoryTeller - Unslander Monica Apr 30 '19 at 08:10
  • 1
    Doesn't `struct { int n; };` introduce the name `::::n`? – YSC Apr 30 '19 at 08:10
  • @StoryTeller There's something I don't get then "A name is a use of an identifier [...] that denotes an entity [...]" and "An entity is a [...] class member, [...]". – YSC Apr 30 '19 at 08:17
  • 3
    @YSC - Yes, and in the scope of a class, a name may refer to a member. The fact you need to fully qualify it, means it doesn't introduce that name at all. This is about declarative regions and scopes. – StoryTeller - Unslander Monica Apr 30 '19 at 08:19
  • @StoryTeller I need to learn _more_. Thank you I'll check that. – YSC Apr 30 '19 at 08:20
  • The current question is about `unnamed structs`, not `anonymous structs`. With the question as-is, your answer is wrong/incomplete. If we can edit and rename the question to anonymous, your answer would be correct. – leetNightshade Apr 26 '22 at 21:42