A Riddle or a Tribute to C++

March 2, 2009

I’m refactoring a class, compiled with MSVC6.

I have a private virtual method - string Dump(SomeStruct *). I’ve verified it is not called from anywhere, both by visual inspection, making it ‘throw 1;’ and making it call abort() and running my unit tests - they all pass. There is one friend class, it does not call the method either. The class does not inherit from anything, and there is one derived class which overrides two methods for purpose of unit testing, but does not touch the method in question. There are no other methods by the same name in the class. There are other virtual methods in the class. The destructor is virtual.

If I remove the method, the code still compiles successfully. But, many assertions then fail in a test which exercises an overridden method in a class we’ll call Foo whose superclass owns a copy of our strange class. This method does not touch the instance, nor does its implementation cause the superclass to treat our strange class any differently.

If I add it back in, the code compiles successfully, and the tests pass again.

What is going on?

Notes:

  • I have verified this behavior with a full rebuild, removing all intermediate targets. I am not using incremental compilation or linking.
  • The mangled name of the method is not longer than the MSVC’s limit, and it is not a template class.
  • Optimizations are turned off.

Answer (in white, select the text to read): The method whose tests fail forgot to memset() a buffer before copying a string of ASCII digits to it, so it worked so long as what was on the stack was not numeric digits before its call. Apparently the vtbl pointer now contains an ASCII digit.

Tags: C++ fixme