traumatized by pointer casting
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > traumatized by pointer casting




Pages (2): [1] 2 »   Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    traumatized by pointer casting  
j0mbolar


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

I was reading page 720 of unix network programming,
volume one, second edition. In this udp_write function
he does the following:

void udp_write(char *buf, <everything else omitted)

struct udpiphdr *ui;
struct ip *ip;

ip = (struct ip *) buf;
ui = (struct udpiphdr *) buf;

I couldn't believe what I was seeing at first.
When I checked the headers for their type definitions
one of them contained bit fields in the struct
and the other struct just contained some unsigned shorts.

A pointer to char is not guaranteed to be
properly aligned for a pointer to struct. In fact
I don't see how this could even work period, even on the
most perverse of systems. I'm right, right? This really
shouldn't work?





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Rich Teer


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

On Fri, 9 Jul 2004, j0mbolar wrote:

> A pointer to char is not guaranteed to be
> properly aligned for a pointer to struct. In fact
> I don't see how this could even work period, even on the
> most perverse of systems. I'm right, right? This really
> shouldn't work?

It's not guaranteed by any standard, but in practical terms,
assuming the same programming model, a pointer is a pointer
(at least as far as their size is concerned).  That is, one
32-bit or 64-bit address is the same size as any other 32-bit
or 64-bit address.

--
Rich Teer, SCNA, SCSA

President,
Rite Online Inc.

Voice: +1 (250) 979-1638
URL: http://www.rite-online.net





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
tweak


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

j0mbolar wrote:
> I was reading page 720 of unix network programming,
> volume one, second edition. In this udp_write function
> he does the following:
>
> void udp_write(char *buf, <everything else omitted)
>
> struct udpiphdr *ui;
> struct ip *ip;
>
> ip = (struct ip *) buf;
> ui = (struct udpiphdr *) buf;
>
> I couldn't believe what I was seeing at first.
> When I checked the headers for their type definitions
> one of them contained bit fields in the struct
> and the other struct just contained some unsigned shorts.
>
> A pointer to char is not guaranteed to be
> properly aligned for a pointer to struct. In fact
> I don't see how this could even work period, even on the
> most perverse of systems. I'm right, right? This really
> shouldn't work?

First, you are going from a char array to a pointer to a
structure as found on page 718.

The ip structure is found in netinet/ip.h .

How did you get so far into the book without noticing that
you will typecast to generic pointers?

Here's a basic one from the first few pages in the book:

snipped from unp.h

#define SA struct sockaddr

from page 6:

[snip]

struct sockaddr_in servaddr;

[snip]

if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0 )

--

The code you point out does basically the same thing.  buf is
just an array instead of a pointer to a structure.  So you have a string
of '0', '0', . . . .

And since you are using pointers, these items find their place
in the structure indirectly.  You cannot typecast a structure
directly.

buff is defined on page 718 as

char buf[sizeof(struct udpiphdr) + 100];

since buf is an array, you do not have use & to pass it
in a function that asks for pointer parameters.

buf

equals

&buf[0]

and the upd_write function on line 43 is:

upd_write(buf, nbytes);

--

I hope that helps.

Brian



--
* Remove x's to send me mail *





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Frank Cusack


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

On 9 Jul 2004 17:45:54 -0700 j0mbolar@engineer.com (j0mbolar) wrote:
> A pointer to char is not guaranteed to be
> properly aligned for a pointer to struct. In fact
> I don't see how this could even work period, even on the
> most perverse of systems. I'm right, right? This really
> shouldn't work?

Right!  How can this work?

For the folks who didn't get it:

char buf[100];
struct foo {
long a;
long b;
char c;
int  d;
};
struct foo *foo_p = (struct foo *) buf;

has the problem that buf has byte-alignment, whereas struct foo has
long alignment.

foo_p->a is not guaranteed to be referenceable.  On some arches it would
cause an unaligned read (slow), on some it just wouldn't work at all.

/fc





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Keith Thompson


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

Rich Teer <rich.teer@rite-group.com> writes:
> On Fri, 9 Jul 2004, j0mbolar wrote: 
>
> It's not guaranteed by any standard, but in practical terms,
> assuming the same programming model, a pointer is a pointer
> (at least as far as their size is concerned).  That is, one
> 32-bit or 64-bit address is the same size as any other 32-bit
> or 64-bit address.

No, not really.  It's common for all pointer types to have the same
size and representation, but there are alignment requirements.
For example:

char buf[100];
char *ptr = buf + 1;

*((int*)ptr) = 42;

is likely to cause a trap on many systems.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
We must do something.  This is something.  Therefore, we must do this.





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Keith Thompson


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 01:50 AM

Frank Cusack <fcusack@fcusack.com> writes:
> On 9 Jul 2004 17:45:54 -0700 j0mbolar@engineer.com (j0mbolar) wrote: 
>
> Right!  How can this work?
>
> For the folks who didn't get it:
>
>   char buf[100];
>   struct foo {
>     long a;
>     long b;
>     char c;
>     int  d;
>   };
>   struct foo *foo_p = (struct foo *) buf;
>
> has the problem that buf has byte-alignment, whereas struct foo has
> long alignment.
>
> foo_p->a is not guaranteed to be referenceable.  On some arches it would
> cause an unaligned read (slow), on some it just wouldn't work at all.

It's certainly true that foo_p isn't guaranteed to be aligned to any
boundary bigger than a byte.  On the other hand, a declared array
object is likely to be word-aligned.  (If you count on this, of
course, your program will fail at the most inconvenient possible
moment.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center             <*>  <http://users.sdsc.edu/~kst>
We must do something.  This is something.  Therefore, we must do this.





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
David Schwartz


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 10:54 PM


"j0mbolar" <j0mbolar@engineer.com> wrote in message
news:2d31a9f9.0407091645.5ad284d7@posting.google.com...

>I was reading page 720 of unix network programming,
> volume one, second edition. In this udp_write function
> he does the following:
>
> void udp_write(char *buf, <everything else omitted)
>
> struct udpiphdr *ui;
> struct ip *ip;
>
> ip = (struct ip *) buf;
> ui = (struct udpiphdr *) buf;
>
> I couldn't believe what I was seeing at first.
> When I checked the headers for their type definitions
> one of them contained bit fields in the struct
> and the other struct just contained some unsigned shorts.

Right, that's because a UDP packet is guaranteed to have a specific
layout at the bit/byte level.

> A pointer to char is not guaranteed to be
> properly aligned for a pointer to struct.

Nevertheless, there is in fact a UDP packet beginning at that address,
and it does in fact have the layout. This is not just any pointer to char,
it's a pointer that he probably got back from a function like 'malloc',
which means it's guaranteed to be adequately aligned to point to any type.

> In fact
> I don't see how this could even work period, even on the
> most perverse of systems. I'm right, right? This really
> shouldn't work?

It will work on most systems. However, it could break on systems where
the buffer is not sufficiently aligned. I'm betting his code made sure the
buffer is sufficiently aligned.

DS







[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
James


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 10:54 PM

On 9 Jul 2004 17:45:54 -0700, j0mbolar@engineer.com (j0mbolar) wrote:

>I was reading page 720 of unix network programming,
>volume one, second edition. In this udp_write function
>he does the following:
>
>void udp_write(char *buf, <everything else omitted)
>
>struct udpiphdr *ui;
>struct ip *ip;
>
>ip = (struct ip *) buf;
>ui = (struct udpiphdr *) buf;
>
>I couldn't believe what I was seeing at first.
>When I checked the headers for their type definitions
>one of them contained bit fields in the struct
>and the other struct just contained some unsigned shorts.
>
>A pointer to char is not guaranteed to be
>properly aligned for a pointer to struct. In fact
>I don't see how this could even work period, even on the
>most perverse of systems. I'm right, right? This really
>shouldn't work?

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,...)
{
char *abuf,*tbuf=buf;
int a=0;

if ((buf&15)!=0)
{
a++;
abuf=(char*)malloc(size+16);
tbuf=abuf & ~15;
memcpy(tbuf,buf,size);
}
udp_write(tbuf,size,...);
if (a!=0)
free(abuf);
}

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.





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Default User


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-10-04 10:54 PM

j0mbolar wrote:

> A pointer to char is not guaranteed to be
> properly aligned for a pointer to struct. In fact
> I don't see how this could even work period, even on the
> most perverse of systems. I'm right, right? This really
> shouldn't work?

Yes but, we're talking platform-specific stuff here. This sort of thing
is so common in UNIX socket programs, that there just aren't likely to
be implementations where it doesn't work. It would destroy too much
legacy code.

The moral, don't look to books like that for ISO standard C. Look to it
as one of the finest tutorials in network programming around. Trust that
the code he has in there has been used and abused for many a year.




Brian Rodenborn





[ Post a follow-up to this message ]



    Re: traumatized by pointer casting  
Dan Pop


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
07-12-04 10:57 PM

In <2d31a9f9.0407091645.5ad284d7@posting.google.com> j0mbolar@engineer.com (
j0mbolar) writes:

>I was reading page 720 of unix network programming,
>volume one, second edition. In this udp_write function
>he does the following:
>
>void udp_write(char *buf, <everything else omitted)
>
>struct udpiphdr *ui;
>struct ip *ip;
>
>ip = (struct ip *) buf;
>ui = (struct udpiphdr *) buf;
>
>I couldn't believe what I was seeing at first.
>When I checked the headers for their type definitions
>one of them contained bit fields in the struct
>and the other struct just contained some unsigned shorts.
>
>A pointer to char is not guaranteed to be
>properly aligned for a pointer to struct. In fact
>I don't see how this could even work period, even on the
>most perverse of systems. I'm right, right? This really
>shouldn't work?

It is the caller's job to ensure that the first argument of udp_write()
is properly aligned for these struct's.  If dynamical allocation is used,
this condition is trivially satisfied.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan.Pop@ifh.de





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 10:03 AM.      Post New Thread    Post A Reply      
Pages (2): [1] 2 »   Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register