GCC lets you forward declare a struct with "class /name/"

This is a discussion on GCC lets you forward declare a struct with "class /name/" within the C++ Programming forums, part of the General Programming Boards category; I'm interested to know whether this is strictly legal and if so why. Could it be a bug in GCC? ...

I don't know what the standard says about it, but a class and a struct are exactly the same except for the default protection. Since this is a forward-declaration, not a definition, the default protection doesn't enter into it and the two things are for all purposes identical.

The class-key or enum keyword present in the elaborated-type-specifier shall agree in kind with the declaration to which
the name in the elaborated-type-specifier refers. This rule also applies to the form of elaborated-type-specifier that
declares a class-name or friend class since it can be construed as referring to the definition of the class. Thus, in any
elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration (7.2), the union class-key shall be
used to refer to a union (clause 9), and either the class or struct class-key shall be used to refer to a class (clause 9)
declared using the class or struct class-key.

As for what a class-key is, if you look that up too, it is a term defined by a list which includes the struct, class and union keywords. So a struct forward declaration could ultimately refer to a class definition, and vice versa, but only union refers to a union, legally speaking.

If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

then in Visual Studio, this program will not link! This is incorrect, but they just can't solve the problem because it would be a major ABI breakage on their part.

This is what happened at work the other day and prompted me to post this. We maintain a codebase that works with gcc and visual studio, though most developers spend most of their time on linux with gcc and for the most part rely on automated builds of visual studio. When we found out this was breaking the windows builds, we all thought... wtf why did this compile with gcc??

Don't get me wrong, I'll take my linux/gcc environment over windows/visual studio any day, but on this specific point, it's a shame and I'm confused by the fact that the standard is like this, because visual studio's behaviour makes a lot more sense to me.

I mean, wouldn't anyone prefer to have their code forward declare a struct with the struct keyword? If you're only building with gcc your compiler will never point this out despite such code being very likely (even certainly?) a mistake.

It's probably only that way because C++ has to compile C. It makes sense to be straight forward like you say, but C++ has two keywords for the same feature, as brewbuck was keen to point out using different words, because the only difference is what default member protection you get using either one. I'd rather Microsoft follow the standard on little issues like these, but what else can we do but complain.

Don't get me wrong, I'll take my linux/gcc environment over windows/visual studio any day, but on this specific point, it's a shame and I'm confused by the fact that the standard is like this, because visual studio's behaviour makes a lot more sense to me.

That's because your mental model differs from the language's view: as far as C++ is concerned, there is no such thing as a "struct". There's just classes introduced with the struct keyword.

That's because your mental model differs from the language's view: as far as C++ is concerned, there is no such thing as a "struct". There's just classes introduced with the struct keyword.

It's actually the other way around, historically. C++ first specified classes as structs with different (private versus public) default access.

Incidentally, a forward declaration of a class (or a struct) can be done using either the struct or class keywords. At least, in standard C++.

Clearly, the Microsoft ABI requires things to be done differently. It escapes me why that should affect end-user code though. It is not exactly a big leap for a compiler to map class and struct keywords in code to the same output (eg name mangling) that complies with requirements of an ABI.

If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Clearly, the Microsoft ABI requires things to be done differently. It escapes me why that should affect end-user code though. It is not exactly a big leap for a compiler to map class and struct keywords in code to the same output (eg name mangling) that complies with requirements of an ABI.