Software: November 2009 Archives

 

November 7, 2009

I happened to be leafing through Stroustrup and noticed that you can overload <code>< and >. This motivated me to write the following program:
#include <iostream>
#include <vector>
typedef int UINT4;

using namespace std; 

class Hack 
{
};

Hack & operator< (Hack &a , Hack &b)
{
 std::cerr << "LT operator\n";

 return a;
}

Hack & operator> (Hack &a, Hack &b)
{
 std::cerr << "RT operator\n";

 return a;
}


int main(int argc, char ** argv)
{
 Hack vector;
 Hack UINT4;
 Hack foo;
 
 vector<UINT4> foo;
 
 return(0);
}

Ask yourself what this code does.

The answer is that it outputs:

LT operator
RT operator

If you focus just on the line vector<UINT4> foo; this looks like a relatively ordinary template instantiation of a vector of type UINT4. This is perfectly normal C++ stuff. However if we expand the scope, it becomes clear that something different is going on: we've defined a new class called Hack and vector, UINT4, and foo are actually objects of type Hack. We've also overloaded the < and > operators. So, what's actually happening here is that we are doing function chaining: We perform operator > on the pair of objects UINT4 and foo. This returns a temporary object of type Hack (in this case the first argument but it doesn't matter). We then perform operator < on set and the temporary variable. And of course since these operators are just function calls, we can do any work we want in them. The examples print stuff to stderr, but that's just an example; you could do anything. And of course this code was written to be moderately transparent while making the point. You could obfuscate it much further with a little effort.

Outstanding!

 

Acknowledgment: Steve Checkoway pointed out to me that whatever crazy type resolution rules C++ follows here make the code work even with the definition of vendor and UINT4 at the top of file. My original version didn't have these and so alleged vector declaration in main wasn't really valid without the definition of Hack

UPDATE Oh great. HTML screws up anything with <foo>. Fixed now.