19

Is this warning anything to worry about? I've read that it can cause erratic behaviour?

It's an example I'm trying to compile, could someone explain to me why the author declares the object as a class but then typedef's it to a structure? Is it perfectly normal to do so if the class is POD?

Thanks.

Adam Naylor
  • 6,172
  • 10
  • 49
  • 69

8 Answers8

27

This warning appears when you have a one type declaration that contradicts another (one says "class", the other says "struct"). Given the one definition rule, all declarations except for at most one must be forward declarations. The warning will generally indicate that a forward declaration of a type is wrong and is usually a simple typo and should be fixed. In this case there should be no side effects, but you really should fix it.

There can be, however, some very nasty things happen if you have type name clashes (perhaps caused by using "using namespace" clauses or global namespace pollution). These warnings could be indicating that you are mixing headers from two different libraries and the type names have clashes. Code compiled under these conditions could do some very unexpected things.

My advice - understand why the warning has appeared and fix it. If the warning is in a third party product, insist that they fix it.

Daniel Paull
  • 6,797
  • 3
  • 32
  • 41
  • 3
    MS Mangling Scheme at http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling#Data_Type: `union` is encoded as `T`, `struct` as `U` and `class` as `V`. – Matthieu M. Feb 01 '11 at 19:46
  • Thanks! , i could find a typedef struct ..., causing me this warning. – HadesDX Sep 14 '15 at 19:13
  • @MatthieuM. Wow, it's very sad they used a different mangling for classes and structs since AFIAK these are the same thing actually (apart having different from default accessibility). – Johan Boulé Aug 29 '22 at 02:09
5

Just to bring the comment by MSalters against this post above to the top level. I have had several hard to find linker errors as a result of VC using the 'class' or 'struct' keyword in its mangling of names.

If you don't expect it to be a problem you can be left scratching your head for hours!

Community
  • 1
  • 1
Richard Corden
  • 21,389
  • 8
  • 58
  • 85
4

Richard Corden is correct - there is a reason MS has this warning. For the MS compiler, decorated (mangled) names include which class-key (struct or class) is used to declare a type. If a function that takes some object as an argument or returns that object is referenced somewhere when the wrong class-key is visible, you will not get a compiler error but the linker will complain because the decorated names differ. The linker error only shows the symbol it's looking for, and it's easy to overlook the class-key mismatch there, so the earlier, more detailed compiler warning is valuable. It's still possible that the two versions don't appear in the same compilation unit, of course, and you will probably be scratching your head for a while if you believe that the only difference is default member visibility.

The difference in mangling conflicts with the C++ standard, which says that forward declarations like struct Foo; and class Foo; are equivalent, and so should use the same mangling.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • 1
    Is this still true on newer MSVC compilers? Or is `class` and `struct` really equivalent for name mangling now? – JDługosz Feb 03 '16 at 04:00
  • 2
    @JDługosz it still seems to be true, see https://godbolt.org/z/oFc3fQ where the struct is mangled as `UStruct` and the class is mangled as `VClass`. – Jonathan Wakely Mar 28 '19 at 08:47
3

I discuss this warning in depth in my blog posting "Is C4099 really a sillywarning?". My conclusion is that it is best turned off. :-) Well, at least for me.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
1

One thing I've seen that can cause this warning is trying to #import the .tlb file from a DLL while also having the same DLL as a reference in your project. I just fixed a problem with this by removing the DLL as a reference from within my project.

JayDub
  • 11
  • 1
1

Although this is considered bad practice, I think there should be no problem mixing class definition and struct declaration, as they are basically the same data type. The main difference is that struct members are by default public, contrary to class members which are private, but otherwise the memory layout is identical.

fbonnet
  • 2,325
  • 14
  • 23
1

In c++ the only difference between a class and a struct is that class's member variables, member functions and base classes are private by default, while in a struct they're by default public; so, the fact that the class is POD should not make any difference here.
I would guess that this warning comes from code maintenance (definition updated somewhere but not somewhere else), and fix the code so that the warning disappears (e.g. using class in the typedef).

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
0

It looks like there is a mismatch between forward declaration and actual declaration. This warning usually comes when you have declared your forward declaration as struct but you declared a class. Making your forward declaration also a class would solve this warning.

Praveen Patel
  • 429
  • 4
  • 11