[uClibc] [RFC][PATCH] Various patches and fixes for gcc-4.x compilers for uClibc and buildroot.

Manuel Novoa III mjn3 at codepoet.org
Mon May 2 05:46:02 UTC 2005


Steven,

On Sun, May 01, 2005 at 09:54:14PM -0500, Steven J. Hill wrote:
> The first two patches for netkitbase and util-linux are a
> result of the deprecation of cast-as-lvalue which happened
> first in GCC-3.4.3. You can read more about it here:
> 
>    http://gcc.gnu.org/gcc-3.4/changes.html
> 
> Comments are welcome before I commit these to buildroot. The
> next patch to uClibc is necessary to build e2fsprogs and is
> also because of this deprecation. I believe my pointer casting
> and such is correct. Manuel had some more obfuscated solutions
> that may work. I would like discussion on the list for this.
> 
> --- /data/svn-ext/uClibc/include/rpc/xdr.h	2005-04-22 19:36:01.914138999 -0500
> +++ ./xdr.h	2005-05-01 20:51:37.480359670 -0500
> @@ -273,10 +273,18 @@
>   * and shouldn't be used any longer. Code which use this defines or longs
>   * in the RPC code will not work on 64bit Solaris platforms !
>   */
> -#define IXDR_GET_LONG(buf) \
> -	((long)ntohl((u_long)*(*(u_int32_t**)&(buf))++))
> -#define IXDR_PUT_LONG(buf, v) \
> -	(*(*(u_int32_t**)&(buf))++ = (long)htonl((u_long)(v)))
> +extern inline long IXDR_GET_LONG(void *buf)
> +{
> +	u_int32_t *tmp = (u_int32_t *) buf;
> +	buf = (void * ) (tmp + 1);
> +	return (long) ntohl((u_long) *((u_int32_t *) tmp));
> +}
> +#define IXDR_PUT_LONG(buf, v)					\
> +	{							\
> +		u_int32_t *tmp = (u_int32_t *) buf + 1;		\
> +		*((u_int32_t *)buf) = (long)htonl((u_long)v);	\
> +		buf = (void *) tmp;				\
> +	}
>  #define IXDR_GET_U_LONG(buf)	      ((u_long)IXDR_GET_LONG(buf))
>  #define IXDR_PUT_U_LONG(buf, v)	      IXDR_PUT_LONG(buf, (long)(v))
>  

Well, IXDR_GET_LONG is broken since the buf vars inside and outside the
inline function are different.  The increment is never seen outside the
body of the function.  IXDR_PUT_LONG has similar behavior to the current
version.  But blocks in standard C do not have values.

I tested the following possible alternative, with additionaly whitespace
for (hopefully) added readability:

#define IXDR_GET_LONG(buf) \
	((long) ntohl((u_long) (((u_int32_t *) \
	     (buf = (void *)(((char *) buf) + sizeof(u_int32_t))))[-1]) ))


#define IXDR_PUT_LONG(buf, v) \
	(((u_int32_t *) \
	  (buf = (void *)(((char *) buf) + sizeof(u_int32_t))))[-1]) \
	= (long)htonl((u_long)(v))

These work providing the 'buf' arg has no side-effects.  Of course,
since the original macros were taking the address of buf, such args
would have been broken anyway.

Manuel




More information about the uClibc mailing list