5

I find the below behaviour really weird, and was just the cause of a strange bug in my code. Is it considered bad to pass objects with references around as const references and then use those refs to change the object they refer to? I get that the reference doesn't change, but I would have assumed that passing the object as a const ref would make all of it's members const as well?

struct wrapr{
    int& a;
};

void mod(const wrapr& aaa){
    aaa.a = 1;
}


int main() {
  int b = 2;
  wrapr a {b};

  mod(a);
  std::cout << b;  // prints 1
  return 0;
}

EDIT:

what is weird is that if I were to declare the struct

struct wrapr{
    const int& a;
};

Then the code would not compile. I guess the mental model I had what when you pass an object by const reference, it is the same as prefixing 'const' on to all of it's member variables. Clearly this is not the case.

user3684792
  • 2,542
  • 2
  • 18
  • 23
  • Doesn't the compiler complain about this: `aaa.a = 1;`? – vahancho Sep 22 '20 at 14:01
  • no, this compiles just fine. (on most recent clang++) – user3684792 Sep 22 '20 at 14:02
  • 3
    Unfortunately that's not really how C++ works. The `const` qualifier only makes the actual members of the structure constant, not what they might reference. – Some programmer dude Sep 22 '20 at 14:02
  • 4
    Basically you have [this](https://stackoverflow.com/questions/2431596/modifying-reference-member-from-const-member-function-in-c) – NathanOliver Sep 22 '20 at 14:07
  • 1
    @Someprogrammerdude but a constant reference (usually) doesn't let you modify what it references – 463035818_is_not_an_ai Sep 22 '20 at 14:15
  • 1
    fwiw, reference members have more quirks, i try to avoid them for anything but narrow scoped, short lived wrappers – 463035818_is_not_an_ai Sep 22 '20 at 14:20
  • If the pointed object is part of the owning object's value, you can change the value of a `const` owning object, which can be problematic. You can get around this with setters and getters or by implementing a distinct type for `const` instances, like the standard does with `const_iterator` types. – François Andrieux Sep 22 '20 at 14:26
  • Thanks everyone. I am surprised I did not know this this, but I guess you never know what you don't know. For the sake of future googlers, I am going to mark this as a duplicate to Nathan Oliver's link. – user3684792 Sep 22 '20 at 14:31
  • 1
    While the dupe is related, I'm not sure this is *actually* a duplicate of that post. – cigien Sep 22 '20 at 15:05

0 Answers0