I was reading C Notes for Professionals, in which, it claims that Compound Literals can only be lvalues. But LLMs have mixed answers upon that stating it could depend upon the context and could be rvalues in certain situations.
When I used godbolt, I found out that scalar compound literals get optimized away as literals by the compiler. For instance, (int) {47}
is same as 47
when compiled to assembly; While the former is an lvaue and the latter is an rvalue. I referenced C23 Standard, N3220.pdf, I was surprised to learn that the standard doesn't use the term rvalue (it uses non-lvalue); My whole life was lie. Few lvalues like (register int) {47}
cannot be addressed at all and yet it is an lvalue. I just realised my understanding of lvalue isn't what I think, could someone please explain it? And also, are Compound Literals always lvalues?
I was reading C Notes for Professionals, in which, it claims that Compound Literals can only be lvalues. But LLMs have mixed answers upon that stating it could depend upon the context and could be rvalues in certain situations.
When I used godbolt., I found out that scalar compound literals get optimized away as literals by the compiler. For instance, (int) {47}
is same as 47
when compiled to assembly; While the former is an lvaue and the latter is an rvalue. I referenced C23 Standard, N3220.pdf, I was surprised to learn that the standard doesn't use the term rvalue (it uses non-lvalue); My whole life was lie. Few lvalues like (register int) {47}
cannot be addressed at all and yet it is an lvalue. I just realised my understanding of lvalue isn't what I think, could someone please explain it? And also, are Compound Literals always lvalues?
2 Answers
Reset to default 6Fet all the books and LLM hallucinations and go straight to the spec (final draft N3096):
6.5.2.5 p6: The value of a compound literal is that of an lvalue corresponding to the unnamed object.
So a clear yes, it is an lvalue.
I was reading C Notes for Professionals, in which, it claims that Compound Literals can only be lvalues.
Correct, see C23 (n3220 draft) 6.5.3.6 §8:
The value of the compound literal is that of an lvalue corresponding to the unnamed object.
But LLMs have mixed answers upon that stating it could depend upon the context and could be rvalues in certain situations.
Don't ask (semi-advanced) programming questions to LLMs.
When I used godbolt., I found out that scalar compound literals get optimized away as literals by the compiler.
Yep they are often pretty heavily optimized but that doesn't mean much.
I was surprised to learn that the standard doesn't use the term rvalue (it uses non-lvalue)
That has pretty much always been the case, rvalue is not a formal term. Probably because the terms lvalue and rvalue are pretty confusing. If we have the ambition to make a language less confusing, we would leave out as many such terms as possible.
(Similarly, if we have the ambition to make a language more confusing, we would rather invent extra terms like glvalue, prvalue, xvalue...)
Few lvalues like (register int) {47} cannot be addressed at all and yet it is an lvalue
The definition of lvalue doesn't mean that it it's an addressable object, only that it is an object. It is stored somewhere.
I think you got it backwards as "if it is addressable then it's a lvalue". Where C rather states that in order to take the address of an object with &
:
- it must be an lvalue
- it must not be declared as
register
or bitfield
Conclusion: all addressable objects are lvalues and not declared as register/bitfield.
(const int) {100}
is also considered lvalue despite of being read-only variable. – Bobby Commented Jan 29 at 21:46(int){42} = 43;
is legal albeit pointless. – Nate Eldredge Commented Jan 29 at 21:48int *p = &(int){42};
is legal too, and not pointless as you can then do stuff with*p
until the end of the block. – Nate Eldredge Commented Jan 29 at 21:55