S
Seebs
I don't think I've ever seen C code in which a macro is #define'd, then
used, then immediately #undef'ed. I can see the argument in favor of
doing it, but in practice most macros are global anyway.
I've done it very rarely, in cases where I used a macro, say, ten or fifteen
times, because it was initialization code of some sort.
Something like:
#define FOO(x) { x, #x }
struct { int value; char *name; } lookup[] = {
FOO(VAL_MIN),
FOO(VAL_ONE),
FOO(VAL_TWO),
{ 0, 0 }
}
#undef FOO
Basically, "cargo cult programming" means programming by rote
without understanding what you're doing. (The roots of the term
are fascinating, but not really relevant.)
I agree that they're not very relevant, but the image is so evocative I
like to explain it.
A lot of good programmers have been reading your code. Not being able
to understand it isn't the problem.
In a way, though, it is.
There are a couple of questions you must ask about any piece of code you
wish to truly understand:
1. What does it do?
2. What was it intended to do?
3. Why does it need to do that?
4. Why is it doing that in this particular way?
The problem here is not that people can't figure out the answer to question
#1 -- surely, most of us can read this code and see what it's doing. The
problem is that if you write something in an unusual way, it leads the reader
to wonder why you did it that way rather than in a more straightforward
way.
Consider:
void
copystring(char *to, char *from) {
void *t = (void *) to;
void *f = (void *) from;
union { int zero; char c; } u;
u.zero = 0L;
u.c = 0;
do {
memcpy(t, f, 1);
t = (void *) ((char *) t) + 1;
f = (void *) ((char *) f) + 1;
} while (memcmp(f, &u.c, 1));
return;
free(&u);
}
An experienced programmer can probably say that this (unless I screwed it
up, no promises) copies the contents of "from" to "to" up to but not
including the first NUL byte encountered in "from".
But that doesn't lead to *understanding* the code. Why do we use t and f
instead of to and from? Why are we using memcmp to see whether the next
byte is 0x0? Why is u a union? Why is u.zero initialized before u.c, and
why was it initialized at all? Why does the code contain a free of a
non-allocated address, but put this after a return statement so it can't
be executed?
All of these questions suggest that one of two things is at issue:
1. The person who wrote this code had a very primitive, at best,
understanding of pointers in C. The code is probably unreliable.
2. There is something extremely unusual going on which you need to
know about.
In fact, it's really:
3. It is a contrived example.
Sandeep's code reads like a contrived example of some sort -- it acts as
though something special is going on, when nothing can be found to justify
the choices made, and that is a big red flag usually.
-s