Const Variable Changed with Pointer in C

In C, can a const variable be modified via a pointer?

const actually doesn't mean "constant". Something that's "constant" in C has a value that's determined at compile time; a literal 42 is an example. The const keyword really means read-only. Consider, for example:

const int r = rand();

The value of r is not determined until program execution time, but the const keyword means that you're not permitted to modify r after it's been initialized.

In your code:

const int x=1;
int *ptr;
ptr = &x;
*ptr = 2;

the assignment ptr = &x; is a constraint violation, meaning that a conforming compiler is required to complain about it; you can't legally assign a const int* (pointer to const int) value to a non-const int* object. If the compiler generates an executable (which it needn't do; it could just reject it), then the behavior is not defined by the C standard.

For example, the generated code might actually store the value 2 in x -- but then a later reference to x might yield the value 1, because the compiler knows that x can't have been modified after its initialization. And it knows that because you told it so, by defining x as const. If you lie to the compiler, the consequences can be arbitrarily bad.

Actually, the worst thing that can happen is that the program behaves as you expect it to; that means you have a bug that's very difficult to detect. (But the diagnostic you should have gotten will have been a large clue.)

C++ const changed through pointer, or is it?

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.

Changing the value of a const variable using pointer in C++

A const is a read-only value. You are trying to do something that is not allowed so you should have Undefined behaviours like this one.

Changing value of const variable using pointers in C

In your first piece of code the address of the constant variable is never assigned to the pointer so its value never changes
Your code should be as

 int *ptr;
ptr = &i;

for the code to work

const variable value is changed by using a pointer

It is possible to change it but the behavior is undefined, as its mentioned in the standard!

Its in c11 under 6.7.3

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. If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined.

Const pointer to a non-const variable

You told the compiler "I am not going to try assigning to *p" (that is really all there is to const), but that says nothing about i.

#include <stdio.h>
void main(void) {
int i = 1;
const int *p = &i;
printf("i=%d\np*=%d\n", i, p);
i = 5;
printf("i=%d\np*=%d\n", i, p);
*p = 10;
printf("i=%d\np*=%d\n", i, p);
}

GCC will complain about assignment of read-only location '*p', but i=5 is fine, since i is not const. Remove the const from *p, or remove the assignment *p=10, and everything is good.

If the reference to i were to somehow disappear, then that memory space would effectively become read-only from the programmer's perspective: the compiler won't let me write to *p, and that is the only handle I have left for that piece of memory.

changing const values via pointers c++

Turns out that I can change the value of the const variable. Am I trespassing into a domain of undefined behaviour or is it allowed?

The former, and as you know UB means anything goes.

I think that the program stores const variables in the same way as normal ones.

It can. Sometimes, it does. Not that you should depend on that.

The compiler is the one which actively prevents me from changing the values when I try to access it directly. I mean to say that the compiler differentiates between const and non-const variables, not the stack itself (on which the variables are stored).

If I can do this, how will I be able to ensure the const-ness of a variable if I mistakenly point to a const variable's location?

Well, unless you venture into the land of UB, there's no problem. And if you do, there's no recourse.

Also, as a side question, does this same program work in other languages too (after making the necessary changes to the syntax, of course)?

Sure, you can write something very similar in all languages allowing direct memory access, in most others you can go over libraries and still do those shenanigans.

A const & refers to a nonvolatile variable. The variable changes. Does the change invalidate the const &?

In C++, can the value of a const & change?

Yes, but not through that reference (ignoring mutable fields).

void foo(const int& c, int& mut) {
std::cout << c << " ";
++mut; // changes `c` if &c == &mut
std::cout << c << std::endl;
}

and

int a = 42;
foo(a, a); // 42 43

does anything prevent an optimizing compiler from merging old_r and new_r into a single constant object, treating the line as though it read as follows?

The as-if rule allows compiler to optimize if visible side effect are the same,

which is not the case here. So your "proposed merge of variable" in your code cannot be done fortunately.



Related Topics



Leave a reply



Submit