On Mon, 11 Nov 2002, Andrew Gallatin wrote: AG> AG>Harti Brandt writes: AG> > On Mon, 11 Nov 2002, TOMITA Yoshinori wrote: AG> > AG> > This is probably not a bug, but a feature. You are not expected to access AG> > a variable through a pointer to a non-compatible type. int and short are AG> > not compatible. (see your ISO C standard on this topic). AG> > AG> > Try to use ntohl(), htonl() for your problem. AG> > AG> AG>On a similar theme, I assume the following is also not safe: AG> AG>static __inline u_int64_t AG>__bswap64 (u_int64_t x) AG>{ AG> u_int64_t ret; AG> u_int32_t *x_ptr, *ret_ptr; AG> AG> x_ptr = (u_int32_t *)&x; AG> ret_ptr = (u_int32_ *)&ret; AG> ret_ptr[0] = __bswap32 (x_ptr[1]); AG> ret_ptr[1] = __bswap32 (x_ptr[0]); AG> AG> return ret; AG>} AG> AG> AG>But does using a union make it safe? AG> AG>static __inline u_int64_t AG>__bswap64 (u_int64_t x) AG>{ AG> union AG> { AG> u_int64_t u64; AG> u_int32_t u32[2]; AG> } AG> ret, old; AG> AG> old.u64 = x; AG> ret.u32[0] = __bswap32 (old.u32[1]); AG> ret.u32[1] = __bswap32 (old.u32[0]); AG> return ret.u64; AG>} AG> AG> AG>FWIW, both *seem* to work correctly using gcc version 3.2.1 and high AG>optimization.
Well, I just had a long discussion with a collegue about the topic. The main problem is in the ISO-C standard, section 6.7 point 4 which states: All declarations in the same scope that refer to the same object or function shall specify compatible types. This makes any fiddeling with a pointer of a type, that is different from the type of the variable illegal. It also makes fiddeling with unions and structs illegal. As far as I understand types are compatible when they have the same type and type qualifiers. Structs are partly compatible when they start with fields of the same type. So the only way to legally swap integer values of any size is via arithmetic. Of course unions and pointers may work with the given compiler version and optimisation level. But, nothing in the standard guarantees you anything. It may be possible that 6.5 (7) the last sentence allows you to access your 32-bit or 64-bit value character-wise (although I'm not sure). harti G> AG>Thanks, AG> AG>Drew AG> -- harti brandt, http://www.fokus.gmd.de/research/cc/cats/employees/hartmut.brandt/private [EMAIL PROTECTED], [EMAIL PROTECTED] To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message