traumatized by pointer casting

D

Dave Thompson

On 9 Jul 2004 17:45:54 -0700, (e-mail address removed) (j0mbolar) wrote:
[Stevens v1 2e p720]
void udp_write(char *buf, <everything else omitted)

struct udpiphdr *ui;
struct ip *ip;

ip = (struct ip *) buf;
ui = (struct udpiphdr *) buf;
It will work on any platform which doesn't enforce alighment
requirements, and on any platform at all provided the pointer passed
is suitably aligned, as I imagine the book's code will do.

If you really want to ensure it's always aligned, add a wrapper
something like this:

void a_udp_write(char *buf,size_t size,...)

The parameter could better be const char *, but back in the '80s that
wasn't reliably portable, and before that didn't exist at all.
{
char *abuf,*tbuf=buf;
int a=0;

if ((buf&15)!=0)

That requires an explicit conversion (cast) -- and then formally as
far as C is concerned the result is implementation-defined, although
it should be correct on any Unix and probably any platform where
BSD-ish sockets make sense at all.
{
a++;
abuf=(char*)malloc(size+16);

Cast not needed in C if malloc is correctly declared, as it must be,
tbuf=abuf & ~15;

Not needed; the value returned by {m,c,re}alloc, if successful, must
be sufficiently aligned for any object type (including struct of
anything) on the implementation. And if it was needed it would be
backwards; you would need to round *up*, into the space allocated.

In general there is no way to automatically determine what the
strictest alignment is, although you can get an upper bound for any
predetermined (finite) set of types by something like
offsetof ( struct { char a; union { long l; double d; } u } , u ).
For IPv4+UDP in particular, we know that no header field requires more
than 4-byte alignment.
memcpy(tbuf,buf,size);
}
udp_write(tbuf,size,...);
if (a!=0)
free(abuf);

Instead of a separate flag variable a, why not just initialize abuf to
NULL, and then unconditionally free() it -- if (still) null it does
nothing, and if non-null it frees the malloc'ed space.

Or, since UDP is lossy anyway, could just do
if( (ulong)buf & 15 ) return;
or to be "nice" about it
... { errno = EPULLTHEOTHERONE; return; }
:)
}

Then you can be certain udp_write() is always working with an aligned
buffer (on a 16 byte boundary here), even if the caller didn't.


James.

- David.Thompson1 at worldnet.att.net
 

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
474,145
Messages
2,570,825
Members
47,371
Latest member
Brkaa

Latest Threads

Top