Amit Singh Tomar
Amit Singh Tomar

Reputation: 8610

Why can I sometimes modify a const object and sometimes not?

I have two pieces of code where I'm trying to modify a value at read-only location. One of them is throwing an error.

1stcode.c

void main()
{
  int const k=9;
  int *p=&k;
  *p=10;
  printf("%d",k);
}

2ndcode.c

void main()
{
      int  const * p=5;
      printf("%d",++(*p));
}

Here 1stcode.c allows me to simply modify the read only memory location but 2ndcode.c throws an error:

error: increment of read-only location '*p'

Why is it so when both locations are read only?

Upvotes: 0

Views: 165

Answers (3)

John Bode
John Bode

Reputation: 123468

From the online C99 standard:

6.7.3 Type Qualifiers
...
5 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.115)

You're attempting to modify the contents of k (an object defined with a const-qualified type) through *p (an lvalue with a non-const-qualified type), thus the behavior is undefined, where "undefined" simply means the standard places no requirement on the compiler to do anything in particular. In this case, the compiler translated the code in such a way that the operation "works", but you shouldn't rely on that behavior being repeatable. A smarter compiler (or a more stringent warning setting) might issue a diagnostic and cease translation at that point. Or it might not. This problem's a bugger to detect in the general case, which is why I suspect the behavior is simply left undefined.

In the second case, you've declared p as a pointer to a const int; you're not allowed to modify *p, which ++(*p) attempts to do.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272507

The 1st example will also not compile if you turn your compiler warning level up.


Note also that in the 2nd example, you're declaring a pointer to address 5, which is not going to ever do anything useful.

Upvotes: 4

Kos
Kos

Reputation: 72261

The first code is incorrect too.

You point with a pointer to int to an object defined as const int and modify this. This is an ill-formed C program, but the compiler doesn't detect the error (well, it probably give you a warning). You can expect bugs to show up because of this, especially if you turn optimizations on (the compiler can assume that the value hasn't changed).

The code still compiles because C is weakly typed and allows implicit conversion between incompatible types (in this case, from const int* to int*.

(Note that this is different in C++, which is more strict and would give you a compilation error if you tried such conversion.)

Upvotes: 2

Related Questions