On Wed, 12 Apr 2000, Mark K. Gardner wrote:

> A mental lapse during the use of recvfrom brought up a question about
> argument error checking. Here is the offending snippet of code
> 
>   if (recvfrom(s, reply, &len, 0, &dest, &dest_len) == -1) {
>     ...
>   }
[snip]                     ^^^^

Well, you can program with macros that wrap functions taking integer
types as args and do a binary & with

"(1 << ((sizeof(type) * CHAR_BIT) - 1))"

on non-pointer args, and gcc will flag a type error on the binary
operand if you pass a pointer there.

I noticed it when I was checking alignment on an alloca() buffer
that I wanted sizeof(long) aligned:

void * buf = alloca(ENOUGH_SPACE + sizeof(long));
while ( buf % sizeof(long)) {
 ++buf;
}

gcc -Wall flagged it as invalid operand to % operator. It did it again
when I was using a triple xor to swap two pointers while walking
a stack of binary tree contexts:

uint32 buf[8];
uint32 * current;
uint32 * parent;

current = &buf[0];  /* working with uint32[4] records */
parent = &buf[4];

do {
  if (/* not first iteration */) {
    current ^= parent;
    parent ^= current;
    current ^= parent;
  }

  /* ... */

gcc -Wall flagged an invalid operand to the bitwise ^ operator
(casting the pointer to unsigned long fixed it in both cases).

So you could have a funky macro:

#ifndef NDEBUG
#define  NOPOINTERS(a, type) (a & (1 << ((sizeof(type) * CHAR_BIT) - 1)))
#else
#define NOPOINTERS(a, type) a
#endif

#define RECVFROM(s, buf, len, flags, from, fromlen) \
recvfrom(NOPOINTERS(s, int), buf, NOPOINTERS(len, int), \
NOPOINTERS(flags, int), from, fromlen)

If you do a debug compile with -Wall and without defining NDEBUG (the
assert() disabling #define), gcc will flag any place that you passed a
pointer for an arg defined as an integer type (where you used the macro
wrapper RECVFROM for the library function) as an invalid operand to binary
&. When you compile a production version with -DNDEBUG, the binary & goes
away.

What a hassle, though: either you use a macro for every
libc function call that uses integer type args or you use the
NOPOINTERS(arg, type) macro in the libc calls themselves. Shouty code.
lclint annotations are probably a better idea (you get more value for
your time and the irritation of doing extra work while coding, imho).

Regards,

Clayton Weaver
<mailto:[EMAIL PROTECTED]>
(Seattle)

"Everybody's ignorant, just in different subjects."  Will Rogers



-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]

Reply via email to