Reputation: 552
In the c++ standard there following definition of an entity can be found:
[basic]/3 ( http://eel.is/c++draft/basic#3 ):
An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, parameter pack, or this.
What is a value in this context?
Is there any rule of the standard using the term entity, where it would make a difference if we didn't consider a value an entity?
Is a pr-value expression a value?
Upvotes: 2
Views: 301
Reputation: 477358
The C++ language standard is infamously vague about formally defining what an "object" and a "value" is. There are efforts to improve this (e.g. N4430), but not before C++17.
At present, one of the definitions of "object" is "a region of storage". The term "value" is never defined; the taxonomy of lvalues and rvalues does not have "value" as its common ancestor, but rather "expression".
For the time being, I would like to offer the following commentary.
Every value is an object: every value has a type, and the type is an object type, which is the type of that object. Conversely, every object has a value. The distinction is in usage: when talking about an object, usually it is the storage of the entity that is under consideration, while values are the result of evaluation of an expression. The value of an object is obtained by evaluating the object, or more precisely by evaluating any expression whose value is that object (tautologically). In yet other words, values are the subjects of computation, and objects are the means by which values are stored.
The distinction comes into play when you consider rules that concern accessing an object through a value. Evaluating an id-expression that names an object yields an lvalue that is that object, and this is the canonical way of accessing that object. But you can produce other values and access the object that way:
unsigned char x;
x = 10; // "x" is an expression and an lvalue
reinterpret_cast<signed char &>(x) = 20; // access through a different lvalue
(Note incidentally that variables can, but need not be objects (they can also be references), but evaluating an id-expression that names a variable always produces a value, hence an object. Conversely, not all objects are variables (e.g. a new
expression produces an object that is not a variable), but all object types can in principle be the type of a variable (subject to constructibility and destructibility).)
Values are more diverse than objects, too. Consider this simple example:
int a;
int b = 10;
b = a;
The last line contains two objects, but several values: b
is an lvalue of type int
that is the object of the variable b
. The expression a
on the RHS is also an lvalue of type int
, being the object of the variable a
. But this value is not suitable for assignment. First, there is an implicit conversion, an lvalue-to-rvalue conversion, which produces a new value. This value is still the same object, but it is a prvalue, and it is that value that is used in the evaluation of the assignment.
Finally, we have temporaries: Are they temporary values or temporary objects? Until recently the Standard was sly and just called them "temporaries", but recently this was made more precise in a few places and now says "temporary objects". Clearly for the purpose of evaluation it does not matter where the value is stored, and the fact that the storage and lifetime are temporary is what matters, so "temporary object" is appropriate. Note that even though you cannot take the address of a temporary object with the built-in address-of operator, such objects can of course have addresses (which can be exported e.g. via a class member function returning this
). It's just not valid beyond the limited lifetime of the temporary object.
In a nutshell: Objects and values are different facets of the same thing, but viewed from different perspectives: respectively the perspectives of evaluation on one side and storage, access and lifetime on the other.
Upvotes: 4
Reputation: 16039
Parsing the chapter in the link, I read
Every name that denotes an entity is introduced by a declaration.
Apparently we can name values! (Are that consts? Edit: Apparently not, but template arguments can be named values, cf. comment by hvd below.). We can name only one thing which is not an entity, that is labels.
Upvotes: -1