0

Consider following code, onData callback invoked and then I assign the const reference to a variable. I want to understand how it works. I was told you can't modify const references but here it looks like you can by assigning to a non-const variable.

void onData(const evpp::TCPConnPtr &socket) {
   evpp::TCPConnPtr connection = socket;
}

In real world application, I assign this to Object Instance's member variable.

jeffbRTC
  • 1,941
  • 10
  • 29
  • 1
    why not? Why do you think the code would modify the `socket` ? – 463035818_is_not_an_ai Apr 26 '21 at 09:25
  • 1
    where exactly you think ```socket``` is modified, here as you were told, object passed by const reference is not modified :) – Karen Melikyan Apr 26 '21 at 09:26
  • @largest_prime_is_463035818 Currently, it doesn't modify the socket. I just want to understand how it works.. It's confusing.. – jeffbRTC Apr 26 '21 at 09:26
  • 2
    its similar to `const int x = 42; int y = x; y = 0;` – 463035818_is_not_an_ai Apr 26 '21 at 09:26
  • 1
    You're not assigning the reference but the value of the referenced object, and assigning *from* a const thing is fine. – molbdnilo Apr 26 '21 at 09:26
  • @molbdnilo Does this creates a copy? If so, how can I avoid it specially when assigning to instance member variables. I'm confused on perf implications too. – jeffbRTC Apr 26 '21 at 09:28
  • This might give you the answer https://stackoverflow.com/questions/7406980/const-reference-to-non-const-object/24384750 – Syed Mohib Uddin Apr 26 '21 at 09:28
  • Yes, it creates a copy. Why do you think that has any noticable impact on performance? It's a `shared_ptr`. – molbdnilo Apr 26 '21 at 09:30
  • @jeffbRTC Where is there any assignment to an instance member variable in your question? – underscore_d Apr 26 '21 at 09:31
  • @jeffbRTC don't worry about performance until you have an actual performance issue. `connection = socket` is a call to [copy assignment operator](https://en.cppreference.com/w/cpp/language/copy_assignment) of `evpp::TCPConnPtr` which, as you can see in the ref, uses either a copy, or a const reference, therefore promising not to change the arguments or only change a copy – gkhaos Apr 26 '21 at 09:32
  • @SyedMohibUddin No, that seems to be about something totally different or opposite to this. – underscore_d Apr 26 '21 at 09:32
  • @underscore_d I didn't add instance stuff here because I wanted to keep it minimal – jeffbRTC Apr 26 '21 at 09:33
  • @gkhaos is there way I could make it const? I don't know to explain this very well to you. Maybe Is there way I could avoid the copy at all? I'm assigning to instance member variable. – jeffbRTC Apr 26 '21 at 09:41
  • @jeffbRTC make sure you understand what pointers are, how references fit in, and why you should never use raw pointers in C++, and what the [Rule of 4 (and a half)](https://stackoverflow.com/a/45762560/9233560) is. If you are curious about how you can help your compiler to copy less the keyword is [copy elision](https://en.cppreference.com/w/cpp/language/copy_elision). However, to use these things well in projects [const correctness](https://isocpp.org/wiki/faq/const-correctness) is key. – gkhaos Apr 26 '21 at 10:46
  • @gkhaos I don't use raw pointers at all. I always use references but this one was confusing because for some some reason.. – jeffbRTC Apr 26 '21 at 10:47
  • @gkhaos Thanks for the links. I am going to research them asap. – jeffbRTC Apr 26 '21 at 10:50
  • @jeffbRTC IMHO you should be familiar with using pointers (but never use them). If you understand pointer and pointer arithmetic lots of things become obviously clear. E.g. a reference is basically a const pointer without the need of dereferencing. A reference-to-const basically is a const pointer-to-const... – gkhaos Apr 26 '21 at 10:51
  • @gkhaos Yes, I used raw pointers in past also I know references does dereferencing under hood but my brain get mad or what.. I don't know how to explain this to you. It also happens when I look at numbers. – jeffbRTC Apr 26 '21 at 10:59

1 Answers1

1

In simple terms, a reference is just an alias to the referenced object. When a reference is const it means you may not modify the object via that reference (the object can be modified via other means, this distinction is important, especially with multithreading). Copying a const reference is like copying the referenced object:

 std::string x = "foo";
 const std::string& x_const_ref = x;  // constant reference to x
                                      // x can be modifed but not via x_const_ref
 //x_const_ref = "moo";  // ERROR !
 x = "bar";              // OK !
 std::string y = x;                   // y is initialized with a copy of x
 std::string z = x_const_ref;         // z is initialized with a copy of x 

y and z will both hold the string "bar", though x is not modified in the last two lines. And if TCPConnPtr has no weird copy constructor then thats basically also what happens in your code (if it does try to modify socket you would get a compiler error).

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185