0

I am stuck at const pointer vs const references. Const pointer like const int* or int const* means that pointer is for const int, and pointer itself is not const. Const type can only be assigned to const reference

const int id = 10;
printf("id=%d\t&id=%p\n", id, &id);
int const *pid = &id;
printf("pid=%p\t*pid=%d\n", pid, *pid);
// *pid = 20;        // fails
*(int *)pid = 20; // works, but WHY???
printf("pid=%p\t*pid=%d\n", pid, *pid);
const int &rid = id;
printf("rid=%d\t&rid=%p\n", rid, &rid);
// rid = 30; // this fails, and afaik nothing can be done to make this writable
// int &ref2 = id; // also fails

The output will be

id=10   &id=0x7ffce84a9e14
pid=0x7ffce84a9e14      *pid=10
pid=0x7ffce84a9e14      *pid=20
rid=20  &rid=0x7ffce84a9e14

References

tbhaxor
  • 1,659
  • 2
  • 13
  • 43
  • 1
    `*(int *)pid = 20; // works, but WHY???` its undefined behavior. – drescherjm Oct 11 '22 at 14:39
  • 5
    The C++ type system protects (to some extent) against mistakes. It doesn't protect against deliberate circumvention. It is not designed to do that. – n. m. could be an AI Oct 11 '22 at 14:39
  • 1
    *"Undefined behavior means anything can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash"*. You can find plenty of dupes for your question. – Jason Oct 11 '22 at 14:40
  • 1
    The [C-style cast](https://en.cppreference.com/w/cpp/language/explicit_cast) attempts `const_cast`, `static_cast`, and `reinterpret_cast` in various combinations. It's an extremely blunt instrument for telling the compiler "I know this looks invalid, but trust me I know more about the underlying data than you in this situation, it's all right". In this case you don't actually know better than the compiler, and get undefined behavior. – Nathan Pierson Oct 11 '22 at 14:43
  • 2
    "What's the point of a crossing, when I can jaywalk." – StoryTeller - Unslander Monica Oct 11 '22 at 14:43
  • `const int * const` is a thing as well, if you're concerned about the pointer itself being `const`. For that syntax I'd prefer the consistency of `int const * const`, but it's subjective. – sweenish Oct 11 '22 at 14:52
  • 1
    @drescherjm it's worth pointing out: since the behavior is undefined, it could be anything, including looking like it worked just fine! But woe be to the person who accepts it and expects it to work the same every time. Also undefined behavior can manifest itself in unrelated parts of your code: [Undefined behavior can result in time travel (among other things, but time travel is the funkiest)](https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633). – Mark Ransom Oct 11 '22 at 15:03
  • 1
    You can use the `-Wcast-qual` flag with GCC to raise warnings for casting const away. You should already see warnings for using the wrong types with the `%p` format specifer which expects a `void *` (if not, you need to turn up warnings with, e.g., `-Wall -Wextra -pedantic`). For const correctness you will need to cast const value addresses to `const void *`. If you do both of these things you should see a warning for the line `*(int *)pid = 20;`. Add `-Werror` to make this a compile time error. – ad absurdum Oct 11 '22 at 15:51
  • Your points make a lot of sense now. Thank you all for taking your time and help me understand this :D – tbhaxor Oct 11 '22 at 17:01

0 Answers0