问题
In short, you can just answer the part about identity, thanks. My main focus of this question is start from 2. about identity, I just tried to provide context/background of my current understanding so it may help you decide the depth when you're writing your answer.
I want to understand the big picture of type system and value categories in C++. I've searched/read many questions and resources online, but everyone has a distinct explanation, so I'm really confused. I'll list the part I can't grasp, if anyone could provide idea about
On cppreference.com, first line:
Objects, references, functions including function template specializations, and expressions have a property called type, which both restricts the operations that are permitted for those entities and provides semantic meaning to the otherwise generic sequences of bits.
my question:
- What does it mean an expression has a type? Is it the type of the final result after evaluation?
- I don't want to learn template at current stage, would this hinder learning about the basic part (from you expert's perspective)? It took me some time to realize that forwarding reference and rvalue reference are different thing, which the former is for template.
Value categories:
I read this answer of - What are rvalues, lvalues, xvalues, glvalues, and prvalues?, the phrase bother me a lot is identity, which also appears on cppreference.com - Value categories (Line 5, glvalue).
my question: can I say that
identity ==
everything I can assign a new value on it?- I saw people using the word address/pointer for it, but is that
has identity iff has address/pointer
? I want the precise term. - I came across the idea of bit-field when reading cppreference.com, it seems like given a bit-field struct
a
, its bit fielda.m
has no address? Is this the reason the word identity is used instead of address/pointer? - I found a blog post explaining this, but it's lvalue definition is counter-intuitive: an lvalue denotes an object whose resource cannot be reused, why not?
- I saw people using the word address/pointer for it, but is that
回答1:
- The type of an expression is the type its result would have, if and when the expression were evaluated. An expression doesn't have to be evaluated, but all expressions have type. Type is a static property.
- There's no precise definition of identity, or an indication of which entities do or do not have identity. It's a muddy concept that is better left alone. Ignore it. Some people say that object identity is its address, but then this concept is useless. Why not just talk about its address then? And what about bit fields? They are objects without addresses, don't they have identity? Others say that lvalues have identity and rvalues don't, but then it's just as redundant.
回答2:
The identity
is a philosophical concept. It's a property of a thing that makes it unique. No two "things" can have the same identity.
A something that has an identity is an entity.
[basic.lval]:
A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
A name inside an expression can only designate one object. So a name inside an expression is an identity. It is defined as an lvalue (for example see expr.prim.id.unqual)
At a given address and at given time there can not be 2 objects of the same type (there can be object nested inside each other, ...). So dereferencing a pointer gives an lvalue.
A reference always designates an entity. So every function that returns a reference when called generates a glvalue.
...
An xvalue is a tag, that can only be generated by a cast (or a bound to a temporary materialization). It is a glvalue that denotes an object or bit-field whose resources can be reused basic.lval
The difference between an xvalue and an lvalue is used to produce efficient code. But xvalue as lvalue are glvalue: they bring the identity of an entity.
...
A prvalue is the result of an expression that is not associated to any object. That is the result of a call to a function that has a non reference return type or the result of some built-in operator calls. In c++ an expression is not an entity, so it has no identity.
prvalues may have a result object, which can be a temporary object. A temporary is an entity, it is materialized when needed (when one try to get a reference to it or when a prvalue is discarded).
The type of an expression is clearly defined in [expr.type]:
If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. [ Note: Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]). — end note ]
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
An expression cannot have reference type.
回答3:
First of all, if you really want to learn C++'s formalisms/details, you should refer to the standards (or drafts of them); instead of wiki pages (which may or may not be correct; although cppreference is usually quite good). See Where do I find the current C or C++ standard documents?.
Having said that, there is no need to study the C++ standard(s) to use the language. Actually, most developers don't, and for sure, they are not meant to learn C++. They are a formal document, not teaching/learning material. So, if you are just learning C++, buy a good book about it. See The Definitive C++ Book Guide and List instead.
What does it mean an expression has a type? Is it the type of the final result after evaluation?
No, it does not need to be evaluated (i.e. at runtime) to have a type. For instance, sizeof expr
has type std::size_t
, yet expr
is not evaluated.
I don't want to learn template at current stage, would this hinder learning about the basic part (from you expert's perspective)? It took me some time to realize that forwarding reference and rvalue reference are different thing, which the former is for template.
Actually, it is the other way around, if you want to learn C++ for practical uses, you definitely need to learn at least the basics about templates (if only to use the standard library and not be completely lost).
However, you don't need to know, formally, everything about how they work about value types, rvalue references or templates themselves to be able to program.
the phrase bother me a lot is identity
There is no definition for "identity of" in the standard. In C++17, it is used in a few places, like when defining glvalue:
— A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
But, indeed, you could say "having identity of" means "actually existing somewhere in memory (if requested)". The best you can do to understand this terminology is reading what Stroustrup wrote:
“has identity” – i.e. and address, a pointer, the user can determine whether two copies are identical, etc.
You can also think about it the opposite way: a glvalue (something that has identity) is any expression that is not a prvalue, if that helps.
来源:https://stackoverflow.com/questions/53443234/whats-the-meaning-of-identity-in-the-definition-of-value-categories-in-c