There's a pretty extensive description of lvalue in What are rvalues, lvalues, xvalues, glvalues, and prvalues?, but this is geared towards c++ and I think a lot of those are not applicable to C.
My understanding of an Lvalue would be as follows:
Arrays are not, but their subscript values may be, as long as those are not an array. For example:
int arr[3][2]; arr // no --> int[3][2] arr[1] // no --> int[2] arr[1][1] // yes --> int
Structs can be directly or through member access, such as
.
or->
, as long as they don't evaluate to an array. For example:struct Member {int id}; Member member = {.id=2}, *member_ptr = &member; member = {.id=3}; // ok member_ptr = &member; // ok member.id=3; // ok member_ptr->id=4; // ok
The address-of
&
operator can not. For example:a = 7; b = &a; &b = &a; // invalid
The value-of
*
operator can be as long as it doesn't refer to an array.int x[2][2] = {{1,2}, {3,4}}; *(x+1)=3; // not ok, evaluates to x[2] *(*(x+1)+1) = 3; // ok
Other than more obvious cases such as doing 7=x
, are there main items that I'm missing in my understanding? Or any items that are incorrect in the above?