Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ const changed through pointer, or is it? [duplicate]

In c it's possible to change const using pointers like so:

//mainc.c
#include <stdio.h>

int main(int argc, char** argv) {
    const int i = 5;
    const int *cpi = &i;

    printf("  5:\n");
    printf("%d\n", &i);
    printf("%d\n", i);
    printf("%d\n", cpi);    
    printf("%d\n", *cpi);   

    *((int*)cpi) = 8;
    printf("  8?:\n");
    printf("%d\n", &i);
    printf("%d\n", i);
    printf("%d\n", cpi);
    printf("%d\n", *cpi);
}

The constant is changed as can be seen in the output: mainc output

If we try the same in c++:

//main.cpp
#include <iostream>

using std::cout;
using std::endl;

int main(int argc, char** argv) {
    const int i = 5;
    const int *cpi = &i;

    cout << "  5:" << '\n';
    cout << &i << '\n';
    cout << i << '\n';
    cout << cpi << '\n';    
    cout << *cpi << '\n';   

    *((int*)cpi) = 8;
    cout << "  8?:" << '\n';
    cout << &i << '\n';
    cout << i << '\n';
    cout << cpi << '\n';
    cout << *cpi << '\n';

    int* addr = (int*)0x28ff24;
    cout << *addr << '\n';
}

The result is not so clear: main output

From the output is looks like i is still 5 and is still located at 0x28ff24 so the const is unchanged. But in the same time cpi is also 0x28ff24 (the same as &i) but the value it points to is 8 (not 5).

Can someone please explain what kind of magic is happening here?

Explained here: https://stackoverflow.com/a/41098196/2277240

like image 349
grabantot Avatar asked Dec 12 '16 08:12

grabantot


2 Answers

The behaviour on casting away const from a variable (even via a pointer or a reference in C++) that was originally declared as const, and then subsequently attempting to change the variable through that pointer or reference, is undefined.

So changing i if it's declared as const int i = 5; is undefined behaviour: the output you are observing is a manifestation of that.

like image 140
Bathsheba Avatar answered Sep 27 '22 21:09

Bathsheba


It is undefined behavior as per C11 6.7.3/6:

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

(C++ will have a similar normative text.)

And since it is undefined behavior, anything can happen. Including: weird output, program crashes, "seems to work fine" (this build).

like image 35
Lundin Avatar answered Sep 27 '22 21:09

Lundin