1

Iam unable to understand why the following code is not throwing error.

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
    const int var = 10; 
    int * ptr = &var;

    printf("%p\n",ptr);
    printf("%d\n",*ptr);
    printf("%d\n",var);

    *ptr = 20;

    printf("%p\n",ptr);
    printf("%d\n",*ptr);
    printf("%d\n",var);
    return 0; 
}

As far as I know variables declared with a const qualifier are stored in a read only mode so how come I can change this with pointers. Please correct me if I am wrong.I ran the code in codechef online compiler

Please suggest me a method in which I can't change value of a variable even by using pointers to it.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 1
    Duplicate of [Can we change the value of an object defined with const through pointers?](https://stackoverflow.com/questions/3801557/can-we-change-the-value-of-an-object-defined-with-const-through-pointers) – Nikos C. Jun 09 '19 at 17:45
  • 1
    TL;DR: Never do this. Also, you should have gotten a warning from the compiler. GCC will say `warning: initialization discards 'const' qualifier from pointer target type`. Clang will say `initializing 'int *' with an expression of type 'const int *' discards qualifiers`. Do not ignore warnings. – Nikos C. Jun 09 '19 at 17:47

1 Answers1

1

That's simply how C works.

As far as I know variables declared with a const qualifier are stored in a read only mode

Declaring a variable as constant only prevents you from modifying it via that variable. There's nothing that prevents you from modifying it via a pointer to non-const, pointing at that variable.

Please suggest me a method in which I can't change value of a variable even by using pointers to it.

Sorry to say it, but the answer is choose another language. If you're going to code C, you have to deal with these kind of stuff often.

One thing to do is to instead declare a pointer to const. You can change int * ptr = &var to const int * ptr = &var. This would make impossible to modify the value in var via ptr, but that is about as far as protection in C goes. You can never write protect the data itself. You can only make sure that the access vectors (my own term in lack of a better one) are forbidden to change the data.

You can also use #define. It has it's pros and cons, but it does the job.

Another thing you can do to make it harder (but not impossible) to modify the data is to hide data structures. You can see an example of that in this question

A very quirky and certainly NOT recommended way is to use string literals. Here is an example:

const uint32_t const * ptr = (uint32_t*)"\x00\x01\x00\x00";

This will give you a "constant" that has the value 256. At least on my machine. I suspect that you will have to know if your machine is big or little endian. It has three different protections. You cannot make this pointer to point to anything else, you cannot use the pointer to change what it is pointing at, and the data is probably in read only memory. Compilers usually puts string literals in read only memory, but they are not required to do so. I suspect that this is undefined behavior. In short, don't do this. It's just a demonstration of what you might have to do in C to get the code relatively but not completely safe.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • I've tried declaring the ptr variable above as const int * ptr = &var; and now it's throwing error. – karthik reddy Jun 09 '19 at 17:45
  • @karthikreddy As it should. The variable is `const`, and now that you declared `ptr` as a pointer to `const int`, the compiler is able to detect that you're trying to write to a `const` variable. – Nikos C. Jun 09 '19 at 17:49