7

Why do I get an error when I run this? I was expecting ptr_ref to be unable to modify the address in which ptr is pointing to but things don't appear to be going as planned.

int b = 3;
int* ptr = &b;
//says something about cannot convert int* to type const int*&
const int*& ptr_ref = ptr; 

Thanks in advance, 15 yr old C++ noob

Wasiim Ouro-sama
  • 1,485
  • 2
  • 12
  • 15
  • not clear from your text, but did you mean that `ptr_ref` should not be able to modify `ptr`, or not be able to modify `b` ? – M.M May 21 '16 at 01:08

3 Answers3

13

ptr_ref is declared not as a const reference to pointer to int, but rather a reference to pointer to const int, so you have a type mismatch. You would have to do

int* const& ptr_ref = ptr;
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Thank you very much yes, I understand very well that the 'const' keyword is part of the type in C++ but man those type declarations can get very troublesome Thank you very much sir. – Wasiim Ouro-sama May 20 '16 at 21:37
  • He stated he wanted the int to be `const`. This would allow it to be mutable, just not the pointer itself. –  May 20 '16 at 21:38
  • @WilliamKappler The question says "expecting... to be unable to modify the *address*", which I interpreted as wanting the pointer to be const. – Brian Bi May 20 '16 at 21:39
  • 1
    There's no such thing as a "const reference". The issue is a reference cannot bind to unrelated types, i.e "const int*" and "int*'. – user6362820 May 20 '16 at 21:39
  • Let me restate it, I want ptr_ref to be unable to modify ptr. – Wasiim Ouro-sama May 20 '16 at 21:41
  • nobody mentioned this yet, but if `b` is supposed to be non-modifiable too, then `const int * const & ptr_ref = ptr;` can be used – M.M May 21 '16 at 01:09
4

The issue is that the types do not match, and thus you cannot create a reference.

int b = 3;
int* ptr = &b;
int*& ptr_ref = ptr;

Is legal.

int b = 3;
const int* ptr = &b;
const int*& ptr_ref = ptr;

Is legal.

int b = 3;
int* ptr = &b;
const int*& ptr_ref = ptr; 

Is a mismatch.

G++'s error message might be helpful to you:

error: invalid initialization of non-const reference of type 'const int*&' from an rvalue of type 'const int*'
  const int*& ptr_ref = ptr;
                        ^

Essentially meaning, it had to create a const int* for this expression, which is an rvalue (essentially a temporary object), and thus you cannot hold a reference to it. A simpler way to put that is, you cannot do what you wrote for the same reason this is illegal:

int& added = 3 + 2;

Depending on your situation, you might solve this simply by removing the reference designation. Most compilers will output identical assembly with or without it, at least when optimized, due to their ability to figure out the fact your variable name is just an alias.

There are even some cases references can perform worse, which depending on your intent, might be worth knowing - I was surprised to know it when I found out.

Community
  • 1
  • 1
  • Thanks I would have held you as the answerer of this Question If you had been sooner, but yeah doing **int* const& ptr_ref = ptr;** solved my issue now I understand that before what I was actually doing was looking for a reference to a const int* but now I understand that's wrong. Thank you vety much! – Wasiim Ouro-sama May 20 '16 at 21:55
  • @funTertain, It's okay to change an accepted answer if a new answer helps more than another one. The accepted answer is the first one shown to future visitors, so ideally, it would be the one that is most helpful on average. – chris May 20 '16 at 22:02
  • @funTertain As I pointed out in my other comment, with `int* const& ptr_ref = ptr;`, the int itself is still mutable. To clarify, I can do: `*ptr_ref = 4;` and the compiler will allow it happily. You should, in my opinion, have *both* `const` designations. It sounds like you want the `int` value `const`, but it's also a very bad idea to leave the pointer mutable. I would write the expression `const int* const ptr_ref = ptr;`. It's really the reference that is the part that makes little sense. –  May 20 '16 at 22:05
  • ...although calling it "ptr_ref" then is sort of crazy. Again, it depends a lot on what you're actually doing. –  May 20 '16 at 22:13
-3

A reference is inherently const, so there is no really point in defining it as int *& const ptr_ref = ptr When you talk about a const reference, it normally means a reference to a const, which is the definition you've used in your question.

[edit] Edited my answer as I had put the const by mistake on the wrong side of the ampersand -- C++ doesn't forgive you [/edit]

ad3angel1s
  • 484
  • 1
  • 5
  • 17
  • Well a if you have a non const reference to a pointer the reference is able to modify the value in which the pointer is pointing to what i was trying to do is restrict the reference from being able to do this. – Wasiim Ouro-sama May 20 '16 at 21:45
  • `int *const& ptr_ref` Is a reference to a const pointer to int (and there is certainly a point to it). The `const` applies to the pointer, not the reference. To apply to the reference, it would be `int *& const`, which is not legal syntax (probably because it is redundant, since, as you stated, a reference is inherently const). – Benjamin Lindley May 20 '16 at 22:06
  • @BenjaminLindley. `int *& const` is not legal syntax because the const identifer can't be applied to a reference (and the compiler will tell you this). Different aspect is `int * const &` which means a reference to a const pointer to non-const int, which is legal, and is what the OP is asking. I've received a downvote on my answer probably because they didn't understand it clearly (or I didn't explain it properly) – ad3angel1s May 20 '16 at 22:26
  • @ad3angel1s: Why are you telling me exactly what I just told you? And the downvote was not likely because someone didn't understand it, but because it was wrong. Now you've corrected it, but given the correction, I'm not sure what this is an answer to, since neither the OP nor anyone else has tried to declare anything as `int *& const`. – Benjamin Lindley May 20 '16 at 22:35
  • 1
    1. A reference is not inherently const, 2. `int *& const ptr_ref` is illegal (`const` cannot appear there) - not sure why you wrote that since OP did not write that, 3. OP did not use a reference to a const. He used a reference to a non-const pointer which points to const. – M.M May 21 '16 at 01:06