[c++] error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’

Wrong form:

int &z = 12;

Correct form:

int y;
int &r = y;

Question:
Why is the first code wrong? What is the "meaning" of the error in the title?

This question is related to c++ pointers reference

The answer is


12 is a compile-time constant which can not be changed unlike the data referenced by int&. What you can do is

const int& z = 12;

References are "hidden pointers" (non-null) to things which can change (lvalues). You cannot define them to a constant. It should be a "variable" thing.

EDIT::

I am thinking of

int &x = y;

as almost equivalent of

int* __px = &y;
#define x (*__px)

where __px is a fresh name, and the #define x works only inside the block containing the declaration of x reference.


int &z = 12;

On the right hand side, a temporary object of type int is created from the integral literal 12, but the temporary cannot be bound to non-const reference. Hence the error. It is same as:

int &z = int(12); //still same error

Why a temporary gets created? Because a reference has to refer to an object in the memory, and for an object to exist, it has to be created first. Since the object is unnamed, it is a temporary object. It has no name. From this explanation, it became pretty much clear why the second case is fine.

A temporary object can be bound to const reference, which means, you can do this:

const int &z = 12; //ok

C++11 and Rvalue Reference:

For the sake of the completeness, I would like to add that C++11 has introduced rvalue-reference, which can bind to temporary object. So in C++11, you can write this:

int && z = 12; //C+11 only 

Note that there is && intead of &. Also note that const is not needed anymore, even though the object which z binds to is a temporary object created out of integral-literal 12.

Since C++11 has introduced rvalue-reference, int& is now henceforth called lvalue-reference.


Non-const and const reference binding follow different rules

These are the rules of the C++ language:

  • an expression consisting of a literal number (12) is a "rvalue"
  • it is not permitted to create a non-const reference with a rvalue: int &ri = 12; is ill-formed
  • it is permitted to create a const reference with a rvalue: in this case, an unnamed object is created by the compiler; this object will persist as long as the reference itself exist.

You have to understand that these are C++ rules. They just are.

It is easy to invent a different language, say C++', with slightly different rules. In C++', it would be permitted to create a non-const reference with a rvalue. There is nothing inconsistent or impossible here.

But it would allow some risky code where the programmer might not get what he intended, and C++ designers rightly decided to avoid that risk.


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to pointers

Method Call Chaining; returning a pointer vs a reference? lvalue required as left operand of assignment error when using C++ Error: stray '\240' in program Reference to non-static member function must be called How to convert const char* to char* in C? Why should I use a pointer rather than the object itself? Function stoi not declared C pointers and arrays: [Warning] assignment makes pointer from integer without a cast Constant pointer vs Pointer to constant How to get the real and total length of char * (char array)?

Examples related to reference

Method Call Chaining; returning a pointer vs a reference? When to create variables (memory management) Reference to non-static member function must be called Cannot find reference 'xxx' in __init__.py - Python / Pycharm c++ "Incomplete type not allowed" error accessing class reference information (Circular dependency with forward declaration) C++ initial value of reference to non-const must be an lvalue Dependent DLL is not getting copied to the build output folder in Visual Studio How to write to error log file in PHP How to reference Microsoft.Office.Interop.Excel dll? Linker Error C++ "undefined reference "