C++, macros, and job security

F

Floobar

Macros sure can be fun -- and profitable. This actually worked -- it
might work for any of you guys too.

The trick is to make your code look sensible, but be actually very hard
to modify without introducing unexpected side effects, so that anyone
hired to replace you will resign, shoot himself, jump off a bridge, or
some such within weeks of exposure to your code that they'd have to
maintain.

At <company name deleted> a friend wrote code like this:

<in some header somewhere>
#define DOUBLE(x) (x+x)

Naturally, elsewhere in the code he had

int j = DOUBLE(i++);

and of course depended on i getting increased by 2, j being twice the
original value plus one, etc.; e.g. if i was 6 it was supposed to end
up 8, and j equal to 13.

During the dot-com bust he predictably got laid off, but the guy who
took over maintaining his code ... well, let's just say he now resides
in a home with no sharp objects or corners and 24/7 on-call assistance
whether he wants assistance or not. >;-)

It started with an obscure bug he had to track down. Eventually, he
found the line

int j = DOUBLE(i++);

and verified that yes, DOUBLE was a macro. He changed the macro to
((x)+(x)) and the above to

int j = DOUBLE(i);
i++;

Of course, now i was 7 instead of 8 and j was 12 instead of 13, under
the same circumstances (i originally 6) as above, and the algorithm
broke. Now there were 2 bugs. The regression had him revert the code
back to the way it was and go on hunting for the real bug. It took
three weeks.

Later that year, he came across the definition of the DOUBLE macro
again, all memory of the previous encounter forgotten, and realized it
was unsafe if the argument had side effects. He assumed it was best to
leave it as a macro, as the intent was probably to provide the most
efficient doubling implementation on each supported platform,
eventually by using #ifdefs and alternative definitions, and the
current implementation was for their main platform where adds were less
expensive than multiplies. So, cleverly, he rewrote it as:

(fix::temp = (x), fix::temp+fix::temp)

and included elsewhere in the header

namespace fix { int temp; }

Of course, one source file now refused to compile at

string s = <stuff>;
<more stuff>;
string s_repeated = DOUBLE(s);

Changing to s_repeated = s + s, partly just to fix it and partly to
futureproof it against an anticipated

#ifdef FOO_PLATFORM
#define DOUBLE (x*2)
#endif

didn't quite fix things. Complex mathematical calculations were now
off, which naturally resulted from code like:

double d;
<stuff>;
foo = DOUBLE(d);

and the huge roundoff errors resulting from d taking a round trip via a
temporary declared as "int".

He changed DOUBLE to an inline function after spending weeks tracking
down the bug, only to be tripped up by

#define inline my_inline

buried seven includes further down and included before DOUBLE. Sure
enough, the code was full of "inline" used as a variable.

It was only after several more events like this (and finding out that
no, this wasn't originally C code ported to C++ later on, so variables
named "inline" didn't have to be grandfathered in in such a clumsy way)
that he began to suspect the awful truth.

I think what clinched it though was the source file with a load of
SUM(x,y) in it and halfway down between one function definition and
another (belonging to the same class at that) a "#include sum2.h". It
read, in its entirety:

#undef SUM
#define SUM(x,y) x-y

(no parentheses even)

I don't think he found this next one amusing either, but he finally
snapped when he encountered "sum2.h" and was fired and charged with
uttering a death threat. After three more firings, an untimely death
(ruled an accident, but believed to have been suicide), and umpteen
requests for transfers, my friend was eventually rehired to maintain
this particular code -- because nobody else could do it.

Oh, the other real gem was:

#ifndef __FOO_H__
#define __FOO_H__

<pages of assorted stuff>

#endif // __FOO_H__

































// and another 150 or so blank lines

#ifdef th\
row
#undef th\
row
#endif // th\
row
#define th\
row scuzzlefuzzlefoobarbazquux )46d{]3[dsf3

He'd been tearing his hair out for weeks trying to figure out why
adding some proper exception handling invariably caused the affected
code to completely fail to compile. He'd even done two or three global
searches of the project files for "throw", suspecting more fun with
macros, but of course grep kept coming up empty...
 
N

noone

Macros sure can be fun -- and profitable. This actually worked -- it might
work for any of you guys too.

The trick is to make your code look sensible, but be actually very hard to
modify without introducing unexpected side effects, so that anyone hired
to replace you will resign, shoot himself, jump off a bridge, or some such
within weeks of exposure to your code that they'd have to maintain.

In response to this post I had originally written a lengthy essay about
maturity and software engineering ethics but then it occurred to me. As
long as folks play the kinds of games you propose, I will continue to have
a better state of job security since I would never do such underhanded
things, and I would only work for/with people who understand and respect
my ethical stand on this point.

But thanks for giving me more things to think about when I interview
candidates. Now I need to figure out a few psychological interview
questions to determine if a candidate might be predisposed to do the kind
of underhanded things you mention.
 
I

implicit_differentiation

noone said:
But thanks for giving me more things to think about when I interview
candidates. Now I need to figure out a few psychological interview
questions to determine if a candidate might be predisposed to do the kind
of underhanded things you mention.

It's just a joke, dude.
 
G

Gianni Mariani

noone said:
On Sun, 31 Dec 2006 13:23:40 -0800, Floobar wrote: ....

In response to this post I had originally written a lengthy essay about
maturity and software engineering ethics but then it occurred to me. As
long as folks play the kinds of games you propose, I will continue to have
a better state of job security since I would never do such underhanded
things, and I would only work for/with people who understand and respect
my ethical stand on this point.

I have yet to meet a CEO who understands.
But thanks for giving me more things to think about when I interview
candidates. Now I need to figure out a few psychological interview
questions to determine if a candidate might be predisposed to do the kind
of underhanded things you mention.

I did come across one guy who did this kind of thing (in another
department) and when I pointed out how difficult it was working with
him, I was told "but he's so productive, no-one else seems to be able to
do his job", he's indispensible !

Sigh.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top