It was always my understanding that l-values have to evaluate, but for kind of obvious and easily explained reasons. An identifier represents a region of storage, and the value is in that storage and must be retrieved. That makes sense. But a program needing to evaluate a literal (for example, the integer 21) doesn't quite make sense to me. The value is right there, how much more explicit can you get? Well, besides adding U for unsigned, or some other suffix. This is why I'm curious about literals needing to be evaluated, as I've only seen this mentioned in one place. Most books also switch up terminology, like "Primary Expression," "operand," or "subexpression" and the like, to the point where the lines begin to blur. In all this time I have yet to see a clear explanation for this particular thing. It seems like a waste of processing power.
-
1*"I've only seen this mentioned in one place"* - care to share? – LogicStuff Sep 02 '16 at 12:51
-
2"l-values have to evaluate" What does that mean? – juanchopanza Sep 02 '16 at 12:52
-
l-values have variable values which need to be retrieved – Arnav Borborah Sep 02 '16 at 12:52
-
1Yes they really do evaluate. For simple types like int, evaluation is just quick move from memory block that this variable is saved to register. Also about other concern, switching terminology - authors don't really want to be ambiguos so they use terms described in language gramatics. – Tomasz Plaskota Sep 02 '16 at 12:53
-
Literals evaluated at compile time. The result is type information and constant value necessary to compiler to form a complete expression – Serge Sep 02 '16 at 12:54
-
What do you mean evaluate? We are talking about the final compiled binary right - ie. asm instructions (and memory locations)? Please give an example in c++ (I+=4; etc) and what you think the asm should/could look like. – ABuckau Sep 02 '16 at 12:59
-
_"The value is right there, how much more explicit can you get?"_ Right where? This question seems to be premised on the notion that C++ is interpreted, but the reality is far, far, far more complicated than you've making out. Rationalising about the translation process in this way is a fool's errand. The best you could do is define "evaluation" (for the scope of this question) as lvalue-to-rvalue conversion ... which, indeed, is not necessary for literals. – Lightness Races in Orbit Sep 02 '16 at 13:00
-
@LogicStuff, the web site www.learncpp.com. Look under "1.5 - A first look at operators," and "Literals,": http://www.learncpp.com/cpp-tutorial/15-a-first-look-at-operators/ – j_burks Sep 02 '16 at 13:01
-
@j_burks: You should learn C++ from [a good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), not from random websites on the internet. – Lightness Races in Orbit Sep 02 '16 at 13:01
-
2@j_burks: The example you now give in comments, is about what expressions mean. It's convenient to describe that in terms of a hypothetical evaluation. That doesn't mean that there's anything going on in the machine code, like computing the value from its specification, or just fetching a value from memory to register. – Cheers and hth. - Alf Sep 02 '16 at 13:04
-
If you have `int a;`, then in the expression `(a)`, `a` is evaluated, and in the expression `sizeof(a)`, `a` is not evaluated. – Kerrek SB Sep 02 '16 at 13:07
-
@Lightness Races in Orbit, that web site is just one source I've been learning from, I do have a few Bjarne Stroustrup books, I don't think I've ever seen him address this in particular. Also, if by lvalue-to-rvalue conversion, I'm going to speculate and guess you might mean copying the bit pattern and applying the l-value's type to interpret the bits? Am I right? Is that what r-value evaluation is? – j_burks Sep 02 '16 at 13:07
2 Answers
A ordinary literal only needs to be evaluated during compilation, by the compiler.
A user defined literal may be evaluated also at run time. For example, after including the <string>
header, and making its ...s
literals available by the directive using namespace std::string_literals;
, then "Blah"s
is a user defined literal of type std::string
. The "Blah"
part is evaluated by the compiler, at compile time. The conversion to std::string
, which involves dynamic allocation, necessarily happens at run time.

- 142,714
- 15
- 209
- 331
-
*A ordinary literal only needs to be evaluated during compilation, by the compiler.* Strictly speaking, that's not completely true for floating point types. See [my answer](http://stackoverflow.com/a/39293264/6394138). – Leon Sep 02 '16 at 13:14
-
@Leon: I can't imagine that there can be more than two possible binary results for each fp literal. So it's no problem generating both at compile time. At run time the rounding mode can just switch between the blocks of values. But since I haven't heard of such scheme, I think it's not done in practice. – Cheers and hth. - Alf Sep 02 '16 at 13:30
-
User-defined literals is not a subject I've gotten into quite yet, though I am aware of them and what they do. Learning that a literal is a "Primary Expression," and by definition an expression "evaluates," has led me to this, whatever you want to call it. But if a literal evaluates at compile-time, it's still evaluating, just not how I thought it was. It's these little pieces of info they don't put in all the books, and I don't like learning incorrect information. Like playing the guitar with your elbows, it may look cool but you can't hit all the notes or play all the songs. – j_burks Sep 02 '16 at 13:49
-
-
But a program needing to evaluate a literal (for example, the integer 21) doesn't quite make sense to me. The value is right there, how much more explicit can you get?
Things are a little more complicated for floating point types. Consider the number 0.1
. In binary it cannot be represented exactly and the closest floating point representation must be selected for it. If you input that number during runtime, the conversion of 0.1
to the binary representation has to respect the rounding mode (upward, downward, toward zero, toward infinity). Strict treatment of floating point arithmetic suggests that conversion of the 0.1
floating point literal to the binary representation should also be performed respecting the rounding mode (which only becomes known during runtime) and therefore cannot be done by the compiler (actually the bigger part of it can be done by the compiler but the final rounding has to be performed during runtime, taking into account the rounding mode).

- 31,443
- 4
- 72
- 97
-
1It's not mandatory to be done at runtime. C++ standard, §2.13.4 states "... If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner. ...". This means a compiler has to *document* how it is done, but it may also be done at compile time. – alain Sep 02 '16 at 13:52