[OpenAFS-devel] latest 1_5_x doesn't compile on fedora 9 gcc-4.3

Jeffrey Hutzelman jhutz@cmu.edu
Wed, 13 Aug 2008 18:41:49 -0400


--On Thursday, August 14, 2008 01:18:34 AM +0300 Dragos Tatulea 
<dragos.tatulea@gmail.com> wrote:

> Hi,
>
>    I'm using the following config options: --enable-debug
> --enable-debug-kernel --enable-warnings --enable-disconnected
> --with-krb5-conf=/path and I'm getting the following compiling error:
> vol-salvage.c:2692: error: lvalue required as left operand of assignment
> Looking into the code we find the line:
>  VNDISK_GET_LEN(vnodeLength, vnode);
>
> Which expands into versions:
># define VNDISK_GET_LEN(N, V) FillInt64(N, (V)->reserved6, (V)->length)
> (AFS_LARGEFILE_ENV enabled)
> and FillInt64 is :
># define FillInt64(t,h,l) (t) = (h); ((afs_uint64)t) <<= 32; (t) |= (l);

This was a bogus fix; applying a cast to the left-hand side of an 
assignment is pretty much never the right thing to do (though it may be 
appropriate to apply a cast to a pointer which is dereferenced to produce 
the lhs).  The result of a cast is not an lvalue.

> Making FillInt64:
># define FillInt64(t,h,l) (t) = (h);t <<= 32; (t) |= (l);
> Solves the problem... I know it's not the right way to go, but what can I
> make to have it compilable with gcc4.3?

This makes the error message go away, but that is not the same thing as 
solving the problem.  In fact, what this does is reintroduce the bug that 
the previous change tried to fix.

The right fix is to rewrite the expression without using the <<= shorthand, 
so that a cast can be applied to the _right-hand_ argument without trying 
to apply it to the left-hand side:

#define FillInt64(t,h,l) (t) = (h); (t) = ((afs_uint64)t) << 32; (t) |=(l);

A simpler form would be:

#define FillInt64(t,h,l) (t) = ((afs_uint64)(h) << 32) | (l);


-- Jeff