Home > Enterprise >  Changing the value of a constant
Changing the value of a constant

Time:07-28

I thought that the & operator wouldn't work for constants because I thought their invokations are replaced with their values at compile time like with macros and that they're rvalues. I wrote this test and the output suprised me.

#include<stdio.h>
int main(void){
    const int a=1;
    *(int*)&a=2;
    printf("%i%i",a,*&a);
    return 0;
}

It outputs 12. I expected it to be 11. Thanks for reaching out.

CodePudding user response:

It outputs 12. I expected it to be 11.

Incorrect expectations.


Casting a pointer to const data to a pointer to non-const data is OK - if the resulting pointer is not used to write data.

const int a=1;
(int*)&a; // OK 

Attempting to write via a pointer that originated as a pointer to const data is undefined behavior (UB). Don't code like that. Anything may happen.

*(int*)&a = ... // Not OK 

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. C17dr § 6.7.3 7

CodePudding user response:

Check out the significance of the volatile keyword below.

Two identical functions, except that TrialB has keyword volatile, and TrialA does not.

TrialA outputs 11, because the compiler believes that variable a is const and cannot change.

TrialB outputs 22, because despite being declared const, the variable is also volatile and therefore needs to be re-examined on every use.

#include<stdio.h>

void TrialA(void)
{
    const int a=1;
    *(int*)&a=2;   // I expected a Warning on this line!
                   // Along the lines of "incompatible typecast from "const int*" to "int*"
                   // But surprisingly, I do not see such a warning.
    printf("%i%i\n",a,*&a);
}

void TrialB(void)
{
    volatile const int a=1;
    *(int*)&a=2;
    printf("%i%i\n",a,*&a);
}


int main(void){
    TrialA();
    TrialB();
    return 0;
}

Output

Success #stdin #stdout 0s 5536KB
11
22
  • Related