[Libvir] [PATCH] to run on IA64

Mark McLoughlin markmc at redhat.com
Tue Feb 20 09:55:28 UTC 2007


Hi,
	Thanks for that ...

On Tue, 2007-02-20 at 13:51 +0900, Atsushi SAKAI wrote:

> > > -    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
> > > -    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr   = inaddr;
> > > +    ((struct sockaddr_in *)((void *)&ifr.ifr_addr))->sin_family = AF_INET;
> > > +    ((struct sockaddr_in *)((void *)&ifr.ifr_addr))->sin_addr   = inaddr; 

> bridge.c: In function 'brSetInetAddr':
> bridge.c:344: warning: cast increases required alignment of target type
> bridge.c:345: warning: cast increases required alignment of target type
> bridge.c: In function 'brGetInetAddr':
> bridge.c:381: warning: cast increases required alignment of target type

	Okay, my understanding of this is that:

  - The warning is caused by -Wcast-align

  - Our problem is that we're casting between pointers to struct 
    sockaddr and struct sockaddr_in, which look like

      struct sockaddr
      {
         unsigned short int sa_family;
      };

      struct sockaddr_in
      {
         unsigned short int sin_family;
         uint16_t sin_port;
         struct { uint32_t s_addr } sin_addr;
      };

  - Because of the uint32_t, struct sockaddr_in is required to be 
    aligned to a 4 byte boundary, whereas on ia64 struct sockaddr is 
    only required to be aligned to a 2 byte boundary

  - If we look at in the context of struct ifreq, though:

      struct ifreq
      {
          ....
          union {
              struct sockaddr ifru_addr;
              ....
              void *ifru_data;
          } ifr_ifru;
      };
      #define ifr_addr ifr_ifru.ifru_addr
      #define ifr_data ifr_ifru.ifru_data

    we see that because of the void pointer in the union, the struct 
    sockaddr is actually guaranteed to be aligned to 8 bytes and so the 
    warning can be ignored.

  - I'd prefer to avoid the void pointer cast as someone could come 
    along and wonder whether the cast is hiding a genuine problem.

  - So, I think I'll go ahead and do it this way instead:

-    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
-    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr   = inaddr;
+    ((struct sockaddr_in *)&ifr.ifr_data)->sin_family = AF_INET;
+    ((struct sockaddr_in *)&ifr.ifr_data)->sin_addr   = inaddr; 

Cheers,
Mark.




More information about the libvir-list mailing list