Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we modify the value of a const variable?

From this article.

Another use for declaring a variable as register and const is to inhibit any non-local change of that variable, even trough taking its address and then casting the pointer. Even if you think that you yourself would never do this, once you pass a pointer (even with a const attribute) to some other function, you can never be sure that this might be malicious and change the variable under your feet.

I don't understand how we can modify the value of a const variable by a pointer. Isn't it undefined behavior?

const int a = 81;
int *p = (int *)&a;
*p = 42; /* not allowed */
like image 479
md5 Avatar asked Sep 03 '12 09:09

md5


People also ask

Can we change the value of a constant variable?

The constant variable values cannot be changed after its initialization.

Can a constant be modified?

Constants are fields whose values are set at compile time and can never be changed.

How will you modify a const variable in C?

Changing Value of a const variable through pointerBy assigning the address of the variable to a non-constant pointer, We are casting a constant variable to a non-constant pointer. The compiler will give warning while typecasting and will discard the const qualifier.


2 Answers

The author's point is that declaring a variable with register storage class prevents you from taking its address, so it can not be passed to a function that might change its value by casting away const.

void bad_func(const int *p) {
    int *q = (int *) p;            // casting away const
    *q = 42;                       // potential undefined behaviour
}

void my_func() {
    int i = 4;
    const int j = 5;
    register const int k = 6;
    bad_func(&i);                  // ugly but allowed
    bad_func(&j);                  // oops - undefined behaviour invoked
    bad_func(&k);                  // constraint violation; diagnostic required
}

By changing potential UB into a constraint violation, a diagnostic becomes required and the error is (required to be) diagnosed at compile time:

c11

5.1.1.3 Diagnostics

1 - A conforming implementation shall produce at least one diagnostic message [...] if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined.

6.5.3.2 Address and indirection operators

Constraints

1 - The operand of the unary & operator shall be [...] an lvalue that designates an object that [...] is not declared with the register storage-class specifier.

Note that array-to-pointer decay on a register array object is undefined behaviour that is not required to be diagnosed (6.3.2.1:3).

Note also that taking the address of a register lvalue is allowed in C++, where register is just an optimiser hint (and a deprecated one at that).

like image 53
ecatmur Avatar answered Sep 22 '22 01:09

ecatmur


Can we modify the value of a const variable?

Yes, You can modify a const variable through various means: Pointer hackery, casts etc...
Do Read next Q!!

Is it valid code to modify the value of a const variable?

No! What that gives you is Undefined Behavior.

Technically, your code example has an Undefined Behavior.
The program is not adhering to c standard once you modify the const and hence may give any result.

Note that an Undefined Behavior does not mean that the compiler needs to report the violation as an diagnostic. In this case your code uses pointer hackery to modify a const and the compiler is not needed to provide a diagnostic for it.

The C99 standard 3.4.3 says:

Undefined behavior: behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements.

NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

like image 42
Alok Save Avatar answered Sep 22 '22 01:09

Alok Save