Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2004:
[Freeciv-Dev] Re: (PR#7121) casting sockaddr and sockaddr_in
Home

[Freeciv-Dev] Re: (PR#7121) casting sockaddr and sockaddr_in

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: brett.albertson@xxxxxxxxxxxx
Subject: [Freeciv-Dev] Re: (PR#7121) casting sockaddr and sockaddr_in
From: "Raimar Falke" <i-freeciv-lists@xxxxxxxxxxxxx>
Date: Sat, 10 Jan 2004 03:02:27 -0800
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=7121 >

On Fri, Dec 19, 2003 at 12:30:22PM -0800, Brett Albertson wrote:
> 
> <URL: http://rt.freeciv.org/Ticket/Display.html?id=7121 >
> 
> During compilation of the current CVS code, I get this on Solaris 9:
> 
> if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../intl -I./aicore    -g -O2
> -Werror -Wall -Wpointer-arith -Wcast-align -Wmissing-prototypes
> -Wmissing-declarations -MT netintf.o -MD -MP -MF ".deps/netintf.Tpo" -c
> -o netintf.o netintf.c; \
> then mv -f ".deps/netintf.Tpo" ".deps/netintf.Po"; else rm -f
> ".deps/netintf.Tpo"; exit 1; fi
> netintf.c: In function `net_lookup_service':
> netintf.c:175: warning: cast increases required alignment of target type
> make[3]: *** [netintf.o] Error 1
> make[3]: Leaving directory `/var/tmp/freeciv/common'
> make[2]: *** [all-recursive] Error 1
> make[2]: Leaving directory `/var/tmp/freeciv/common'
> make[1]: *** [all-recursive] Error 1
> make[1]: Leaving directory `/var/tmp/freeciv'
> make: *** [all] Error 2
> 
> 
> This is due to the following line:
> 
> sock = (struct sockaddr_in *) sa;
> 
> In the code, sa is declared as:
> 
> struct sockaddr *sa
> 
> I think casting sockaddr to a sockaddr_in type in Solaris is a bad
> thing.  I'm not sure how to fix it.

Tricky. Options:
 - change all struct sockaddr to struct sockaddr_in in the function
 prototypes (no IPv6 support)
 - copy the data:
   struct sockaddr _sa=*sa;
   struct sockaddr_in _sock;
   assert(sizeof(_sa)==sizeof(_sock));
   memcpy(_sock,_sa,sizeof(_sa));
   sock=&_sock;
 - create a new union type
   union {
     struct sockaddr addr;
     struct sockaddr_in addr_in;
   } my_sock_addr;
  and pass this union type around. Because of the union the pointer
  will have to correct alignment.
 - ignore it
 - cast it away with a cast to "void *".

Note that this is a real error for CPUs which have real alignment
rules (i386 doesn't have these) AND the "struct sockaddr *" producer
chooses the weaker alignment of struct sockaddr and so doesn't satisfy
the alignment requirements of struct sockaddr_in.

The union approach is the most clean one. We should do it.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "There are three ways to get something done. Do it yourself, hire someone
  to do it for you or forbid your kids to do it."




[Prev in Thread] Current Thread [Next in Thread]