Monday, 12 October 2009

Lost Souls of memory managment strike forth from the grave

One of the horrible things about memory managers that note down your file and line is the necessity to differentiate them in some way if they're going to be "if safe".

By if-safe, I mean, safe to have mid argument. Any clever memory manager stuff takes line and file to tell you where your allocations were made. The hierarchical one that I wrote for platform was okay, but it's nature lead to needing to invent the "Again" method. That is, I had to because i didn't know about the double indirection of macro token expansion. Of course, I was a fool to think that macros were ever safe, but i didn't realise quite how ghastly they could be.

Would you beleive that the code below:

#define ThingOnLine( X ) Concat( int t ## X, __LINE__ )
#define Concat( X, Y ) Concat2( X, Y )
#define Concat2( X, Y ) X ## Y

compiles fine and does what you think it should, but the code below:

#define ThingOnLine( X ) Concat( int t ## X, __LINE__ )
#define Concat( X, Y ) X ## Y


That's right.

Try it.

There's no substitute for looking at an error log and going WTF.

Simply put, the __LINE__ doesn't get expanded straight away, it takes a couple of indirections until it gets around to it. The reason is probably to do with how dumb the pre-processor is. It could be that it's doing all it can on each pass, and it needs to be double indirect in order to get around to putting numbers on __LINE__ statements on it's first pass before its allowed to join them up in subsequent ones.

1 comment:

Unknown said...

I think I just threw up a little.