Reinhold Kainhofer <reinhold at kainhofer.com> wrote: >If I use "unsigned char*", then I get no warning. However, I fail to see why >using an additional variable makes a difference... > >This does not work (&b[0] is a pointer to an unsigned char, right?): > unsigned char b[4]; > htole32a(&b[0], value); > >while this does: > unsigned char b[4]; > unsigned char *bp=&b[0]; > htole32a(bp, value);
The first argument to htole32a must be an lvalue. It is used in the left-hand side of an assignment by htole32a; this is the exact meaning of lvalue. b[0] is an lvalue. It is certainly well-defined to write something like: b[0] = 2; &b[0] looks like it should be the address of the first element of b, and indeed it is, but it is not an lvalue: it does not denote a target (such as a variable) to which some value may be assigned. It is not a pointer type, which can be dereferenced by the * operator. What is needed for the first argument of htole32a is a pointer P that can be used in a statement like: *P = 2; The statement: unsigned char * bp=&b[0]; is well-defined: the variable bp is assigned a value which is the address of the unsigned char b[0]. bp is an actual variable, therefore it is an lvalue and an acceptable first argument to ntole32a. A statement such as: *&b[0] = 2; is invalid according to the C language grammar (even if you, a human, can say you know what it should mean). That is why the compiler complains when it parses: htole32a(&b[0], value); but the compiler is happy with the correct: htole32a(bp, value); because that expands into: *bp = value;