Question:
What is the difference between constant x and & xx?
#include <iostream>
using namespace std;
int main() {
const int x = 2;
const int &xx = 3;
cout << x << endl;
cout << xx << endl;
return 0;
}
Why is &
needed?
Answer:
Semantically, these two declarations are different.
const int x = 2;
const int &xx = 2;
In the first case, a constant object is declared, which is initialized with an integer literal. It may not even be allocated memory for it if you do not need to access the object's memory. The compiler can use the value of this constant object at compile time. For instance,
const int x = 2;
int a[x];
The size of the declared array is known at compile time.
Regarding this announcement
const int &xx = 2;
then a temporary object is first created for the value of expression 2
, and then a reference is defined to this temporary object. Where this temporary object will be located in memory – this will be known at the stage of program execution. Note that the temporary object itself is not constant. It is simply the result of evaluating an expression with a single operand, the integer literal 2.
Because of this, there are different reactions from compilers when using the xx
reference.
So, for example, the MS VC 2016 Community compiler does not compile the following code snippet
const int &xx = 2;
int a[xx];
Error message
Error C2131 expression not defined by constant 623
As I think, MS VC ++ 2016 Community in this case focuses on the following provision of the C ++ standard about constant expressions (5.20 Constant expression, p. No. 2)
- a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or
Note that it is stated that a reference to a constant object must be present, while the temporary expression that initializes the reference of the above code snippet is not constant. Therefore, the compiler issues an error message.
This same code snippet compiles successfully at www.ideone.com. This compiler, apparently, is based on another sub-clause of this clause of the C ++ standard
- a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e ;
This subclause does not say anything about the constancy of a literal temporary object. It is sufficient that it be of a literal type.
So if you dig into the C ++ standard, and also look at the behavior of compilers, the differences will be obvious. 🙂