4

Possible Duplicate:
constants and pointers in C

I have this little piece of code. I am using a gcc compiler:

#include <stdio.h>

int main()
{
    const int a=10;
    int *d;
    d=&a;
    *d=30;
    printf("%d %d\n",a,*d);
    return 0;
}

It gives a warning on compiling:

"assignment discards qualifiers from pointer target type"

But no error. The output is: 30 30

Then doesn't it defy the purpose of maintaining a const variable whose value is fixed throughout the program execution (please correct me if I am wrong)?

Community
  • 1
  • 1
Trigger
  • 109
  • 1
  • 1
  • 3
  • 3
    Yet another reason to actually not ignore warnings. Your code is in no way _guaranteed_ to work. In fact, I'd say you're lucky it doesn't crash and burn :) – Joachim Isaksson Nov 03 '12 at 18:44
  • 1
    Note that the answer to the duplicate is a bit off per the standard, which does not speak of "readonly memory", only what behavior is defined and which is not (this is not). It's up to the compiler to decide where `a` is placed. Undefined behavior doesn't mean "an error will occur". That would be defined behavior. – Ed S. Nov 03 '12 at 18:48
  • As @JoachimIsaksson said, it is undefined behavior. Please do enough research before asking questions on stackoverflow. – CCoder Nov 03 '12 at 19:05
  • 3
    It's undefined behavior because the assignment `d=&a;` violates a constraint. The compiler could (and IMHO should) have rejected the program rather than merely warning about it, but the standard only requires a "diagnostic" for any constraint violation, and a warning satisfies that requirement. You can use `gcc -pedantic-errors` to force gcc to treat constraint violations as fatal errors. – Keith Thompson Nov 03 '12 at 19:55
  • Is there a reason gcc (and MSVC) doesn't treat `d=&a` as an error? It seems to me that it's not permitted by the standard and should be diagnosed as an error. Do compilers not treat it as an error because there would be too many 'false positives'? – Michael Burr Nov 03 '12 at 23:05
  • @KeithThompson Could you be specific about the clause that would make `d=&a;` undefined in C? `*d=..;` is clearly undefined as per C99 6.7.3:5, but if ``d=&a;` is undefined, how are we supposed to sort arrays of `const char*` with `qsort`? – Pascal Cuoq Nov 04 '12 at 00:12
  • @PascalCuoq: from my reading of the standard, without a cast the `d=&a` assignment should result in an error rather than just a warning. Both gcc and MSVC only issue a warning. As far as sorting arrays of `const char*` - it the data is actually `const` you can't. If the data isn't donst, but the pointer has been qualified with `const`, you can legitimately cast away the `const` qualifier, but that shouldn't happen implicitly. As I asked about in my comment, I suspect gcc and MSVC are somewhat loose with this for historical/legacy reasons. – Michael Burr Nov 04 '12 at 01:48
  • @PascalCuoq: `d=&a` is a constraint violation; N1570 6.5.16.1p1, 3rd bullet: the type pointed to by the LHS (`int`) doesn't have all the qualifiers of the type pointed to by the RHS (`const int'). A compiler must issue a *diagnostic* (which can be just a warning) for any program containing a constraint violation: N1570 5.1.1.3. I *think* the behavior of a program violating a constraint (or syntax rule) is undefined by omission; there may be an explicit clause that I'm missing. – Keith Thompson Nov 04 '12 at 04:17
  • @MichaelBurr: The standard requires a *diagnostic* for any violation of a constraint or syntax rule; a non-fatal warning can be a valid diagnostic. The only time a compiler is actually required to reject a translation unit is when it contains a `#error` directive that isn't skipped. – Keith Thompson Nov 04 '12 at 04:18
  • You are not allowed to assign a const int* value to a int* pointer. That would violate the rules of const-correctness. In fact, what you are doing is an error in C. C compilers traditionally report it as a mere "warning" to avoid breaking some old legacy code. – Rahul Tripathi Nov 03 '12 at 18:45

3 Answers3

4

const is not a guarantee. It's only a promise. Promises can be broken. The compiler warns when this happens, but is otherwise not required to prevent it, since there could be cases where bypassing the const-ness might be useful.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96
2

The above behavior is undefined. As this example shows, you can get different values as well. Explanation for this output is - compilers optimize the code and replace const variables with their values. So we can see a difference when we do printf("%d %d %u %u\n",a,*d,&a,d); which would actually have been modified to optimize as printf("%d %d %u %u\n",10,*d,&a,d);

Do not rely on any of these outputs. Actual behavior is not defined by the standard.

CCoder
  • 2,305
  • 19
  • 41
0

You shouldn't do that and the compiler is giving you that warning for a reason. However, C/C++ will let you do anything you want. It is up to you to write clean code.

You can reflect the constness of that value by using:

int const * d =  &a;    

Then, modifying what d points to will produce warnings and errors.

Michael McGuire
  • 1,034
  • 9
  • 20