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
How to Omit the Double-Braces for Std::Array in C++14
Undefined Reference to Mempcy@Glibc_2.14 When Compiling on Linux
In Which Access Control Context Are Concepts Evaluated
C++ Circular Dependency in Header Files
How to Get Size C++ Dynamic Array
How to Parse CSV Using Boost::Spirit
Dependent Name Resolution & Namespace Std/Standard Library
How to Check If a File Has Been Opened by Another Application in C++
Why Infinite Recursion Leads to Seg Fault
Calculate A*A Mod N Without Overflow
Are the "Usual Arithmetic Conversions" and the "Integer Promotions" the Same Thing
Overload Resolution with Std::Function