12

I would like to get GCC to produce a warning that VisualStudio produces when it finds a name that has been declared with both class and struct. (Warning 4099) This usually results from forward declarations such as:

struct Base;
...
class Base { ... };

VS actually fails to link in this case so I've promoted the warning to an error. Since this project is cross-platform I would like to also discover this issue when compiling with GCC -- otherwise I can accidentally check in code that won't work in VS.

Is there any switch, or method, to get GCC to also reject, or warn, about such class/struct declaration mismatches?

NOTE: From the comments it is uncertain whether this warning is legitimate. For my question it isn't relevant since the condition causes the linking in VisualStudio to fail (I can't just ignore the warning). Thus I'd just like to identify the problems using GCC so my windows compiles don't suddenly stop working.

Antonio
  • 19,451
  • 13
  • 99
  • 197
edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267
  • 2
    VS is actually incorrect in its warning. The code is fine. :-) – Bo Persson Apr 19 '11 at 06:49
  • @Bo, I believe the same thing. If it were just a warning I might disable it. However, at link time it will actually produce errors since it compiles different modules with different mangled names for the class. – edA-qa mort-ora-y Apr 19 '11 at 07:03
  • @Bo: no it's not. The standard explicitly states it. It just takes a convoluted mind to actually differentiate between the two... – Matthieu M. Apr 19 '11 at 07:33
  • From the standard, 9-4 does seem to indicate, that like a `union`, `struct` is a distinct type (though still a class type). However, 9.1-2 says a class definition will hide any class of the same name. So if my struct comes before my class it is technically valid, and thus the linker error is a defect in VS. – edA-qa mort-ora-y Apr 19 '11 at 07:59
  • 2
    @Matthieu: yes it is. 7.1.5.3/3 says "either the `class` or `struct` *class-key* shall be used to refer to a class declared using the `class` or `struct` *class-key*". – Mike Seymour Apr 19 '11 at 08:53
  • 1
    I found a discussion on the subject http://stackoverflow.com/questions/4866425/mixing-class-and-struct where Jerry had unearthed the same quote as @Mike above and interpreted it as saying that they could be freely exchanged. There was much discussion in the comments to his answer though. – Matthieu M. Apr 19 '11 at 09:04
  • @BoPersson VS is non-compliant in this regard; `struct` and `class` should be interchangeable – Lightness Races in Orbit Dec 18 '19 at 12:29
  • @BoPersson, VS actually generates a different symbol name depending on whether the type is `struct` or `class` (and will use the first _class-key_ that the compiler discovers, i.e. forward declarations make a difference to symbol names!). – Mark Ingram Dec 18 '19 at 15:08
  • Since gcc 10 it is possible to use ‘-Wmismatched-tags’ https://stackoverflow.com/a/66640473/2436175 – Antonio Mar 22 '21 at 19:20

3 Answers3

5

Since version 10 also gcc, like clang, offers the -Wmismatched-tags flag https://stackoverflow.com/a/66640473/2436175

Antonio
  • 19,451
  • 13
  • 99
  • 197
4

gcc does not care about the difference. The Itanium ABI mangles class and struct the same way, leaving them as pure syntactic difference.

Clang has -Wmismatched-tags to activate this detection, but I could not find the gcc equivalent (if any).

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • I know GCC doesn't care. I don't think the C++ standard care either. But silly VS does care, and it breaks at link time. That's unfortunate if GCC doesn't have a way to notice. – edA-qa mort-ora-y Apr 19 '11 at 07:02
  • @edA-qa mort-ora-y: Actually the standard does care, I just can't find where it's precised, and looking for `struct` in it does not help much... – Matthieu M. Apr 19 '11 at 07:32
  • 1
    @MatthieuM. no the standard doesn't care. A forward declaration `struct Foo` is identical to a forward declaration `class Foo` and that implies they must use the same mangling. See [dcl.type.elab] p3 which says you can use either `struct` or `class` in an elaborated-type-specifier for a class, and it doesn't matter whether it was declared with `struct` or `class`. – Jonathan Wakely Mar 28 '19 at 09:05
0

What version of VC++ are you using. There was an error in VC++ 6.0 which meant that it treated struct and class differently, but that's been fixed in later compilers; I don't get any warning with VC++ 2005, for example.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • VS 2008. I don't mind fixing the problem, as I agree with the warning that something is wrong. I just want a way to detect it using GCC. – edA-qa mort-ora-y Apr 19 '11 at 08:48
  • You may think that there is something wrong, but the language says that there isn't; I don't get even a warning with VC++ 2005, and I don't think that you can get one from g++. – James Kanze Apr 19 '11 at 08:52
  • No, you don't get a warning from gcc. From the various comments it is unclear whether this is even wrong. That aside however, it breaks with the VS linker, thus it'd be nice to identify them. – edA-qa mort-ora-y Apr 19 '11 at 09:25
  • 2
    @edA-qa mort-ora-y Yes. I've just verified that the bug is still in VC 2005---I would have expected that it had been fixed. The obvious "best" solution is just to drop that compiler:-), but I know that it's not always (or even often) a good solution. Failing that, given that you can't get a warning from g++, the simplest solution is probably to just standardize on one: always `class` or always `struct`; `grep` will turn up any violations of the rule. – James Kanze Apr 19 '11 at 10:44
  • 1
    The mangling difference still seems to be present today: https://godbolt.org/z/oFc3fQ – Jonathan Wakely Mar 28 '19 at 09:05