- Modern C++:Efficient and Scalable Application Development
- Richard Grimes Marius Bancila
- 374字
- 2021-06-10 18:27:50
Working with Expressions
An expression is a sequence of operators and operands (variables or literals) that results in some value. Consider the following:
int i;
i = 6 * 7;
On the right side 6 * 7 is an expression, and the assignment (from i on the left-hand side to the semicolon on the right) is a statement.
Every expression is either an lvalue or an rvalue. You are most likely to see these keywords used in error descriptions. In effect, an lvalue is an expression that refers to some memory location. Items on the left-hand side of an assignment must be lvalues. However, an lvalue can appear on the left- or right-hand side of an assignment. All variables are lvalues. An rvalue is a temporary item that does not exist longer than the expression that uses it; it will have a value, but cannot have a value assigned to it, so it can only exist on the right-hand side of an assignment. Literals are rvalues. The following shows a simple example of lvalues and rvalues:
int i;
i = 6 * 7;
In the second line, i is an lvalue, and the expression 6 * 7 results in an rvalue (42). The following will not compile because there is an rvalue on the left:
6 * 7 = i;
Broadly speaking, an expression becomes a statement by when you append a semicolon. For example, the following are both statements:
42;
std::sqrt(2);
The first line is an rvalue of 42, but since it is temporary it has no effect. A C++ compiler will optimize it away. The second line calls the standard library function to calculate the square root of 2. Again, the result is an rvalue and the value is not used, so the compiler will optimize this away. However, it illustrates that a function can be called without using its return value. Although it is not the case with std::sqrt, many functions have a lasting effect other than their return value. Indeed, the whole point of a function is usually to do something, and the return value is often used merely to indicate if the function was successful; often developers assume that a function will succeed and ignore the return value.