0

I have a function that remove the const attribute of the int* and change the value of the variable it point to, but it doesn't work since I pass a variable and reference it in the formal reference?

This is my code:

#include <bits/stdc++.h>
#include <iostream>
#include <map>
using namespace std;
typedef unsigned char UINT8;

int ll(const int &r)
{
  *(const_cast<int *>(&r)) = 5;
  // cout<<const_cast<int*> (&r)<<endl;
  //*(&r)=5;

  cout << r << endl;
}

int main()
{
  const int a = 1;

  ll(a);

  cout << a << endl;
}

I expected the value shown in the function to be the same as the one in main(), but it's different.

Max Langhof
  • 23,383
  • 5
  • 39
  • 72
Caiyi Zhou
  • 143
  • 1
  • 9
  • 7
    Attempting to modify a constant variable leads to *undefined behavior*. End of story. – Some programmer dude Sep 25 '19 at 08:20
  • Unrelated to your problem, but please read [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) as well as [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) Also please don't create your own local type-aliases, use [the standard fixed-width integer types](https://en.cppreference.com/w/cpp/types/integer) instead, like `std::uint8_t`. – Some programmer dude Sep 25 '19 at 08:22
  • Compilers trust you completely. When you wrote `const int a = 1;` you said to the compiler, "the value of `a` will never change", but that was a lie. When you lie to the compiler, strange things can happen. – molbdnilo Sep 25 '19 at 08:31
  • you mean the compiler doesn't allow me to modify the value of const variable? but why *(const_cast(&r)) = 5 is allowed in the function body since r is an reference of a? I thought compiler will report errors but I passed unexpectedly and the value is changed successfully to be 5 – Caiyi Zhou Sep 25 '19 at 08:38
  • @molbdnilo forgot to @ you – Caiyi Zhou Sep 25 '19 at 09:38
  • @CaiyiZhou When you promised that `a` would never change, the compiler relied on that promise and replaced all uses of `a` with its unchanging value, 1. – molbdnilo Sep 25 '19 at 09:38

1 Answers1

6

Attempt to modify const-qualified object a causes Undefined Behavior. Language allows to alter types and/or qualifiers of references using reinterpret_cast and/orconst_cast but it is always programmer's responsibility to ensure that the object being accessed through a reference really has appropriate type and qualifiers.

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • but why *(const_cast(&r)) = 5 is allowed in the function body since r is an reference of a? I thought compiler will report errors but it passed unexpectedly and the value is changed successfully to be 5 – Caiyi Zhou Sep 25 '19 at 08:39
  • @CaiyiZhou *Undefined behaviour is undefined.* Anything can happen. As to why the compiler's not complaining: if `a` had been declared as `int` instead of `const int`, the code would be perfectly correct. Casting away a `const` qualifier when accessing an object which is not actually `const` is not a problem. Doing it on an actually `const` object *is* a problem. – Angew is no longer proud of SO Sep 25 '19 at 08:41
  • r is const actually cause compiler report errors of *(&r)=5 which has been commented by me in the function body. I only cast away pointer of r not r itself, I do so for compilers does not report errors of this line *(const_cast(&r)) = 5 – Caiyi Zhou Sep 25 '19 at 08:59
  • @CaiyiZhou `*(const_cast(&r))` yields a reference of `int` which only effects overload resolution, however the object being referenced is still const qualified and should not be changed. Adjusting qualifiers on reference (or pointer) to object does not change qualifiers on the object itself. Language allows to alter types and qualifiers of references using `reinterpret_cast` and `const_cast` but it is programmers responsibility to ensure that object being accessed through a reference really has stated type and qualifiers. – user7860670 Sep 25 '19 at 09:07