开发者

C function returns const pointer that is assigned to nonconst pointer - warning not error

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

const int * func()
{
    int * i = malloc(sizeof(int));
    (*i) = 5;    // initialize the value of the memory area
    return i;
}

int main()
{
    int * p = func();
    printf("%d\n", (*开发者_如何学编程p));
    (*p) = 3;       // attempt to change the memory area - compiles fine
    printf("%d\n", (*p));
    free(p);
    return 0;
}

Why does the compiler allow me to change (*p) even if func() returns a const pointer?

I'm using gcc, it shows only a warning on the int * p = func(); line : "warning: initialization discards qualifiers from pointer target type".

Thanks.


Your program is not valid. C forbids implicitly removing a const like that, and in conformance to the spec GCC should give you at least a warning for that code. You would need a cast to remove the const.

Having consumed a warning for that, you can however rely on the program to work (although not anymore from a Standards point of view), because the pointer is pointing to a malloc'ed memory area. And you are allowed to write to that area. A const T* pointing to some memory doesn't mean that the memory is thereafter marked immutable.

Note that the Standard doesn't require a compiler to reject any program. The Standard merely requires compilers to sometimes emit a message to the user. Whether that's an error message or warning and how the message is emitted and whatever happens after that emission, isn't specified by the Standard at all.


The compiler and the C language "allow" you to do all manner of stupid things, especially if you ignore warnings. The conversion of a const int* to int* is the only point at which the compiler can detect that there's anything amiss here, and it issued a warning for that conversion. That's as much disapproval as you'll get, and it's why you shouldn't ignore warnings.

Since the behavior of this program is defined (by GCC, to be the same as if you'd explicitly cast to const int*), it's at least possible that what you've done really is what you intended to do. That's why the code is accepted.


You are turning a const pointer into a normal pointer, which would essentially allow you to change the pointer. You are breaking the "contract" you made by returning a constant pointer, but since C is a weakly-typed language it is syntactically legal.

Basically GCC is helping you here. Syntactically it is legal to turn a const pointer into a regular one, but chances are you didn't want to do that so GCC throws a warning.

Read design by contract.


first of all, the memory is valid in main, because it's stored on the heap and hasn't been destroyed/freed. So the compiler just complain a warning to you.

If you try

const int * p = func();

then of course (*p) = 3 will be error.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜