[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