In life, you will inherit all sorts of things: traits from your direct ancestors, knick-knacks from relatives you tolerated, and sometimes, even money! Of course, there are other things in life that you inherit that you might not even want. The gene for some debilitating disease. The urn filled with the ashes of a relative you particularly despised. Code.

Gerhardt was employed at a C++ shop. Their main product used a third party library. Perhaps used is not quite right; abused is more apt. Every single field that was public (whether it looked like it should be public or not) was ab/used to the max.

At some point, the vendor upgraded the library, and much to the chagrin of all involved, lots of those formerly public variables and methods were now protected. Some of you will say that perhaps they should just change their code to use the library as the vendor intended. Real programmers™ with any real experience in OO languages will immediately think "OK, we can just wrap the protected stuff with our own classes and continue to access the formerly public stuff as before."

class SecretiveLegator {
  ...
  protected:
      TopSecretType   topSecretMember;
}

class LegacyHunter : public SecretiveLegator {
  public:
      void setTopSecretMember(const TopSecretType &value) {
	      topSecretMember = value;
      }
	  
      const TopSecretType & getTopSecretMember() const {
          return topSecretMember;
      }
}

Now, with an available work-around worthy of Wile E. Coyote, the forbidden fruit was once again hanging within reach of all who wanted it:

static_cast<LegacyHunter &> (secretiveLegator).setTopSecretMember(newValue);

Of course, if the vendor ever demoted those now-protected fields and methods to private...

Gerhardt inherited another piece of nifty engineering; the getOrSet method. Basically, it allowed you to either get the value of a variable, or set the value of that variable at any given time. What a marvel, you only needed one method! Of course, if you had never seen it and casually came upon it, you had one of those moments when you looked at something, had no clue what it was or why it existed, and mumbled those three magic little words under your breath. Then you look at the source code and wish you hadn't:

public:
    void getOrSet(bool getOrSet, TheType &x) {
	 if (getOrSet) {
	    this.x  = x;
	 } else {
		x = this.x;
         }
    }

Inheritance is usually a static thing. You inherit a trait from mommy or daddy; not some random stranger. Gerhardt's company employed the truly innovative pattern of dynamic inheritance. This is not dynamic casting, mind you, no! There was a BaseClass that consisted of a giant union of all of their structs, allowing code to read and write the underlying data by means of any one of those structs.

Each of the union's member structs represented one or more (possibly nested) derivations from BaseClass. BaseClass had a list of virtual and pure-virtual methods like so:

  baseClass *elements = (BaseClass *) new char[nElements * sizeof(BaseClass)];

To initialize the elements array, the proper union struct was used to write the appropriate kind of data to the element. Then the powdered unicorn dust was applied. They had several global variables, one for each subclass of BaseClass. The pointer in the array that represented a given sub-class was initialized like this:

  *(void **) p = *(void **) &globalInstanceOfTheSubclassOfBaseClass;

For those of you not up on C++ mojo, that copies the virtual function table pointer from the sample subclass to the start of the memory that they wanted to represent the subclass instance. By overwriting a given pointer with the value from a different subclass, you could completely change all the virtual functions that would be invoked for that particular subclass. Calling a given virtual method would result in code from the last subclass to which the pointer had been set being called.

You may ask, how was this creature used? The GUI had the ability to specify the type of object at any given node in their system. Once the pointer for the object was overwritten, the virtual function table was effectively patched and the resultant code would then behave as though the data in the union/struct was that of the selected subclass.

Of course, virtual function tables aren't the only pointers that can be abused. Gerhardt found where they were using member-pointers (as quasi enums) to tell the method (not what it had to do, but) who called it. The method would then deduce what it was supposed to do based upon who was invoking it.

This was particularly fascinating when inline functions were on a call stack that spanned different DLLs (where the address of the function was different in each and every one).

After a long period of the most bewildering crashes, he stripped out all of the function pointers, and switched the entire mechanism to an ordinary enum.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!