Kaz Kylheku (kaz@cafe.net)
Mon, 01 Feb 1999 23:57:47 -0800
> Do you have a smug bastard of a programmer in your office whose code
> always
> seems to work with a minimum of debugging? If so, then heres a few
> #defines
> to keep them busy.
>
> #define main Main /* Now try to link this! */
Actually it might still link if you are on some antiquated system whose linker
does not distinguish external names that differ only in case. :) :)
> #define stdout stderr /* No problems, until you pipe it */
Actually there could be plenty of other problems, like if you include <stdio.h>
after the #define. You have to sneak in the #define after the include of
<stdio.h> for this one to be effective. Or muck with <stdio.h> itself, but I
would consider that cheating. :)
Thus the perpertraion of this particular prank is somewhat clumsy.
> #define while(x) if(x)
Sneaky; unless the programmer uses do/while loops. They are not all that
uncommon, and are often used in defining macros that simulate void-returning
functions:
#define do_a_few_things(X) do { \
S1; S2; S3(X); \
} while (0)
Still, the replacement of while by if here would cause some pretty baffling
syntax error.
> #define struct union /* Great space saver */
Detected trivially at compile time if there ever appears an initializer
for the aggregate type, since an union initializer with more than one
element is a constraint violation. Other than that, this is quite nasty.
The devastating effect of these pranks will be amplified if you do it in
a Microsoft development environment, because their compiler has awful
diagnostics and is unhelpful in pinpointing the source of errors that occur
while parsing nested header file inclusions. :)
Now for my own contribution:
#define break return
This is quite horrible because it's legal to replace any break statement by a
return without introducing a syntax error. What might give away the prank
would be warnings about unreachable code. However, since both break and return
transfer control unconditionally, there are many situations in which replacing
a break by return won't introduce unreachable code, or in which the replacement
introduces instances of unreachable code that the compiler doesn't bother
detecting (after all, it has more pressing work to do than solving the halting
problem, right? :) And you can always cover your tracks by sneaning in some
#pragma or compiler command line option that defeats the warning. :)
Some venomous variations on the above theme:
#define continue break
or
#define continue return
Continue is rare enough that this could introduce a defect that goes undetected
for a long time. (Whereas break occurs often, because it's necessary for
writing the most common switch statements).
Of course, pranks like this are ultimately irresponsible and even potentially
criminal because they could result in software defects whose effects are
damaging. But such irresponsibility is not an uncommon ingredient in pranks
of all kinds, right? Pranks do go terribly wrong sometimes and it's no use
apologizing afterward. Even if no real harm results, you never know how people
will react.
This particular type of prank is only mildly funny if the programmer discovers
the error immediately and then goes crazy looking for it. If the error is not
discovered, you have to sneak it out again---but what if you are run over by a
bus meanwhile or choke on your sandwich? I suppose you have to incorporate a
note into your last will and testament which calls for the undoing of the prank
and hope that it's executed before the release date of the software that you
damaged. That is, if the scope of your concern for others endures beyond your
own death, of course.
This archive was generated by hypermail 2.0b3 on Mon 01 Feb 1999 - 23:02:50 PST