1

why is it possible to change the value of the constant z in the C++ snippet below? What is the meaning of (int&) in the 5th line? Note that the addresses of x, y, z are different (cout << &x << &y << &z). Thank you very much!

int x = 2;
int y = 3;
const int z = x;
cout << z; // the result is 2
(int&) z = y;
cout << z; // the result is 3
andreipb
  • 79
  • 8
  • 1
    Well, the way you're doing it is cheating a bit, isn't it? In language like C and C++ you can write memory directly, so in theory it's possible to override any language safety feature. – Robert Harvey Feb 25 '19 at 13:58
  • 2
    `(int&)z` is like telling the compiler "Hey I know you are a bity picky about const and all that, but I am more clever than you, so please treat `z` as a `int&` and just do what I tell you without caring about const correctness", is that really what you want ? ;) – 463035818_is_not_an_ai Feb 25 '19 at 13:59
  • Whenever you see (or feel the need to write yourself) a C-style cast, then that's a red flag that there's something bad going on. – Some programmer dude Feb 25 '19 at 13:59
  • 1
    note that your code has undefined behaviour, you can modify a `const` value under certain circumstances, but you are not allowed to do so – 463035818_is_not_an_ai Feb 25 '19 at 14:01
  • With that said, the `&` is needed to make `z` an lvalue that can be assigned to. Otherwise if just `(int) z` was used, that would not be possible to assign to it. – Some programmer dude Feb 25 '19 at 14:02
  • 1
    I don't know what book you are reading, but if threw that at you before preparing you for it, you should ditch it for a [better one](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – StoryTeller - Unslander Monica Feb 25 '19 at 14:03
  • 2
    [Any attempt to modify a const object during its lifetime results in undefined behavior.](https://stackoverflow.com/a/52710485/1597714) (except class members declared mutable) – AMA Feb 25 '19 at 14:07
  • 4
    It's also "possible" to drive 100 mph through a 30 mph zone. Try `const int z = 2;` instead and see what happens. – molbdnilo Feb 25 '19 at 14:17

1 Answers1

0

Because in this case we have a cast on the left side of an assignment expression that tells to compiler we are forcing our identifier in order it behaves as a not read-only reference to its memory location, and since we are knowingly "forcing" a behaviour, compiler trust us and allows this assignment.

In some cases this is potentially dangerous, as when you assign the const identifier with a literal value, because it is not standard how compilers implement this initialization, in fact some compilers seems that replace the occurrences of identifiers with the literal values, as well as a macro expansion, so you have to pay a very close attention doing this operation.

Ciro Corvino
  • 2,038
  • 5
  • 20
  • 33
  • Thanks, but do you mean "forcing our identifier TO behave as a reference to a memory location"? Also, I am not totally convinced by the compiler "trusting" us -- in many cases it doesn't trust us very much... – andreipb Feb 25 '19 at 14:47
  • 1
    A cast operation is always a way to force the "nature" of an identifier established by its type and access modifiers. With a "cast" we change the type of an identifier to another type. Obviously only some type of trasformations are allowed, because if compiler detects an incompatible cast operation (types are objectively different and don't allow values passage without loss) then it doesn't trust us anymore :) this is because it is sure that it is not possible to convert a type to another. – Ciro Corvino Feb 25 '19 at 15:03
  • Sorry, i have said a wrong thing about const memory location access by address or reference. I fix my answer.. – Ciro Corvino Feb 26 '19 at 10:47