Search code examples
c++classvirtualvirtual-functionsanonymous-class

Virtual tables on anonymous classes


I have something similar to this in my code:

#include <iostream>
#include <cstdlib>

struct Base
{
  virtual int Virtual() = 0;
};

struct Child
{
  struct : public Base
  {
    virtual int Virtual() { return 1; }
  } First;

  struct : public Base
  {
    virtual int Virtual() { return 2; }
  } Second;
};

int main()
{
  Child child;
  printf("ble: %i\n", ((Base*)&child.First)->Virtual());
  printf("ble: %i\n", ((Base*)&child.Second)->Virtual());

  system("PAUSE");
  return 0;
}

I'd expect this to give this output:

ble: 1
ble: 2

and it does so, when compiled under GCC (3.4.5 I believe).

Compiling and running this under Visual Studio 2008 however, gives this:

ble: 2
ble: 2

What is interesting, is that if I give the Base-derived structs names (struct s1 : public Base), it works correctly.

Which behavior, if any, is correct? Is VS just being prissy, or is it adhering to the standard? Am I missing something vital here?


Solution

  • It is visible how MSVC is getting it wrong from the debugging symbols. It generates temporary names for the anonymous structs, respectively Child::<unnamed-type-First> and Child::<unnamed-type-Second>. There is however only one vtable, it is named Child::<unnamed-tag>::'vftable' and both constructors use it. The different name for the vtable surely is part of the bug.

    There are several bugs reported at connection.microsoft.com that are related to anonymous types, none of which ever made it to "must-fix" status. Not the one you found though, afaict. Maybe the workaround is just too simple.