【问题标题】:C function returns const pointer that is assigned to nonconst pointer - warning not errorC函数返回分配给非常量指针的常量指针-警告不是错误
【发布时间】:2011-10-12 01:08:24
【问题描述】:
#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;
}

为什么编译器允许我更改(*p),即使func() 返回一个常量指针?

我正在使用 gcc,它只在 int * p = func(); 行显示警告:“警告:初始化丢弃来自指针目标类型的限定符”。

谢谢。

【问题讨论】:

  • 有办法让编译器显示错误而不是这个警告吗?
  • @prinfede:-pedantic-errors-Werror
  • OP 返回的不是 const 指针,而是指向 const(或只读)对象的指针。

标签: c function pointers return-type


【解决方案1】:

编译器和 C 语言“允许”您做各种愚蠢的事情,尤其是在您忽略警告的情况下。 const int*int* 的转换是编译器可以检测到这里有任何问题的唯一点,并且它会针对该转换发出警告。你会得到尽可能多的反对,这就是为什么你不应该忽视警告。

由于该程序的行为是定义的(由 GCC 定义,与您显式转换为 const int* 相同),至少有可能您所做的确实是您打算做的。这就是代码被接受的原因。

【讨论】:

    【解决方案2】:

    您的程序无效。 C 禁止像这样隐式删除 const ,并且按照规范 GCC 至少应该为您提供该代码的警告。你需要一个演员来删除const

    已经为此发出警告,但是您可以依靠程序来工作(尽管从标准的角度来看不再如此),因为指针指向一个 malloc 的内存区域。你可以写信到那个区域。指向某个内存的const T* 并不意味着此后该内存被标记为不可变。

    请注意,该标准不要求编译器拒绝任何程序。该标准仅要求编译器有时向用户发出消息。无论是错误消息还是警告,以及消息是如何发出的,以及发出后发生的任何事情,标准都没有规定。

    【讨论】:

      【解决方案3】:

      您正在将const 指针转换为普通指针,这实际上允许您更改指针。你通过返回一个常量指针打破了你所做的“契约”,但由于 C 是一种弱类型语言,它在语法上是合法的。

      基本上 GCC 在这里为您提供帮助。从语法上讲,将 const 指针转换为常规指针是合法的,但您可能不想这样做,因此 GCC 会发出警告。

      阅读design by contract

      【讨论】:

        【解决方案4】:

        首先,内存在 main 中是有效的,因为它存储在堆上并且没有被销毁/释放。所以编译器只是向你抱怨一个警告。

        如果你尝试

        const int * p = func();
        

        那么(*p) = 3当然会出错。

        【讨论】:

          猜你喜欢
          • 2022-07-06
          • 2021-08-25
          • 2022-11-10
          • 2011-03-27
          • 1970-01-01
          • 1970-01-01
          • 2011-08-02
          相关资源
          最近更新 更多