Adi
Adi

Reputation: 731

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

I wrote some thing similar to this in my code

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

Does this work on all compilers? Why doesn't the GCC compiler notice that we are changing a constant variable?

Upvotes: 6

Views: 5965

Answers (4)

John Bode
John Bode

Reputation: 123458

Online C 2011 draft:

6.7.3 Type qualifiers

...
6 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.133)
133) This applies to those objects that behave as if they were defined with qualified types, even if they are never actually defined as objects in the program (such as an object at a memory-mapped input/output address).

Emphasis added.

Since the behavior is left undefined, the compiler is not required to issue a diagnostic, nor is it required to halt translation. This would be difficult to catch in the general case; suppose you had a function like

void foo( int *p ) { *p = ...; }

defined in it's own separate translation unit. During translation, the compiler has no way of knowing if p could be pointing to a const-qualified object or not. If your call is something like

const int x;
foo( &x );

you may get a warning like parameter 1 of 'foo' discards qualifiers or something similarly illuminating.

Also note that the const qualifier doesn't necessarily mean that the associated variable will be stored in read-only memory, so it's possible the above code would "work" (update the value in x) in that you'd successfully update x by doing an end-run around the const semantics. But then you might as well just not declare x to be const.

Upvotes: 4

K Scott Piel
K Scott Piel

Reputation: 4380

Bad programmer. No Moon Pie!

If you need to modify a const, copy it to a non-const variable and then work with it. It's const for a reason. Trying to "sneak" around a const can cause serious runtime issues. i.e. the optimizer has likely used the value inline, etc.

const int x=1;
int non_const_x = x;
non_const_x = 2;

Upvotes: -1

Keith Thompson
Keith Thompson

Reputation: 263257

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.)

Upvotes: 11

Neil Townsend
Neil Townsend

Reputation: 6084

There is a good discussion of this here:Does the evil cast get trumped by the evil compiler?

I would expect gcc to compile this because:

  • ptr is allowed to point to x, otherwise reading it would be impossible, although as the comment below says it's not exactly brilliant code and the compiler should complain. Warning options will (I guess) affect whether or not it's actually warned about.
  • when you write to x, the compiler no longer "knows" that it is writing to a const, all this is in the coders hands in C. However, it does really know, so it may well warn you, depending on the warning options you've selected.

whether it works or not, however, will depend on how the code is compiled, the way const is implemented for the compile options selected and the target CPU and architecture. It may work. Or it may crash. Or you may write to a "random" bit of memory and cause (or not) some freaky effect. It's not a good coding strategy, but that wasn't your question :-)

Upvotes: -1

Related Questions