Let's imagine this function:
C* get(C* c, int offset) {
return c + offset;
}
I would like to know if a call to this function is evaluated as a prvalue:
C array_c[3];
C* c2 = get(array_c, 2);
Is get(array_c, 2) a prvalue?
According to Value categories page on cppreference:
- a glvalue (“generalized” lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;
- a prvalue (“pure” rvalue) is an expression whose evaluation either :
- computes a value that is not associated with an object
- creates a temporary object and denotes it
- an xvalue (an “eXpiring” value) is a glvalue that denotes an object or bit-field whose resources can be reused;
- an lvalue (so-called, historically, because lvalues could appear on the left-hand side of an assignment expression) is a glvalue that is not an xvalue;
In our example, the expression get(array_c, 2) points to an already exising object that doesn't expire after the call. So we can say it is an lvalue. Moreover, we can write *get(array_c, 2) = C{}; to assign a value to the expression.
However, there are two points that make me think it is not an lvalue. First of all, in the same page of cppreference:
The following expressions are prvalue expressions:
- a function call or an overloaded operator expression, whose return type is non-reference
In our example, the get function returns a non-reference so, according to this definition, the call should be evaluated as an prvalue.
Also, I'm wondering if get(array_c, 2) is indeed a temporary that makes it a prvalue and *get(array_c, 2) is an lvalue because we can assign a value to it.
What do you think? Is the function call evaluated as an lvalue, a prvalue (or something else)?