Why can the following be done? And what is happening here ?:

const int& a = 10; int* b; *b = a; 
  • here it writes to a random memory address (b is not initialized). Therefore, in short - UB. And by the way the compiler warns. - pavel
  • Ah, got it. Thank! (UB - is this behavior uncertain? (Unexpected Behavior)) - wcobalt
  • Yes, UB = undefined behavior. Only "undefined", not "unexpected". - HolyBlackCat
  • Here, instead of const int& a = 10; with the same success could be int a = 10; . Or instead of *b = a; you could immediately make *b = 10; . - HolyBlackCat

2 answers 2

In this code snippet

 const int& a = 10; int* b; *b = a; 

not

Assigning a pointer to a non-constant reference to a constant

In this code snippet, you are trying to write to memory at an undefined address (because the pointer, if it has automatic memory, is not initialized, or if it has static memory, then initialized with a null constant) the value 10 referred to by reference a . That is, the code fragment has an undefined behavior.

Most likely you had in mind the following code snippet.

 const int& a = 10; int *b = &a; 

In this code fragment, an attempt is made to initialize a non-constant pointer (i.e., a pointer to a non-constant object) with the address of the constant object referenced by a .

This code is also considered ill-formed, that is, it does not meet the standard. Otherwise, you could change the constant object through this non-constant pointer.

It would be correct to write

 const int& a = 10; const int *b = &a; 

That is, the reference is constant, and the pointer points to a constant object.

Below is a demonstration program.

 #include <iostream> int main() { const int& a = 10; const int *b = &a; std::cout << "*b = " << *b << '\n'; } 

Its output to the console:

 *b = 10 

Both the link and the pointer both refer to a constant object.

Consider another similar code.

 #include <iostream> #include <iomanip> int main() { int i = 10; const int &a = i; int *b; b = &i; // b = &a; std::cout << "&a == &i is " << ( &a == &i ) << ", &a == b is " << ( &a == b ) << '\n'; } 

In this program you can write

 b = &i; 

since both the pointer and the object to which the pointer will refer, are both non-constant.

But you can not write (in the program this sentence is commented out)

 b = &a; 

since in this case there is a constant link in the right-hand part, that is, it is considered that the link refers to a constant object, and in the left-hand part there is not a constant pointer.

However, the addresses of the objects referenced by the link and the pointer are the same, since they refer to the same object.

  • It's not entirely clear why int *b = &a; suddenly "also has an indefinite behavior." This option is immediately definitely wrong (ill-formed). And no indefinite behavior is necessary. - AnT 2:42 pm
  • @AnT Good point. I corrected the text. - Vlad from Moscow

I suspect that you were interested in something else - something like

 const int& a = 10; int* b = a; 

Those. You wanted to access the constant value / variable through the pointer and change it. If this were possible, then, of course, it would be a violation of the security system, constancy - in a word, a reason to ask - why is this possible?

But the fact is that the link is an absolute synonym for what it refers to. And it cannot refer to something else — what it refers to is determined when the link is created, and the assignment of a link to something else turns out to be an assignment of value — the link itself as a pointer to something does not change.

You can write

 const int& a = 10; const int * b = &a; 

But you can't

 const int& a = 10; int * b = &a; 

If this is not what you were interested in - then I'm sorry, but it is completely incomprehensible to what then your question " why is this possible " applies?

  • Yes, I was interested in just that. The name of the question is worded incorrectly in view of the fact that I did not fully understand what was going on here. Thanks - wcobalt 4:03 pm