【问题标题】:Declaring and initializing a completely `const` `char *argv[]`声明和初始化一个完全的`const``char *argv[]`
【发布时间】:2021-09-18 22:09:31
【问题描述】:

我尝试将 argv 值分配给常量指针,认为将非常量分配给 const 变量是安全的。

不幸gcc投诉:

> make CFLAGS=-Wall mein
cc -Wall    mein.c   -o mein
mein.c: In function ‘main’:
mein.c:5:30: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
  const char *const*const a = argv + 1;
                              ^~~~
mein.c:5:26: warning: unused variable ‘a’ [-Wunused-variable]
  const char *const*const a = argv + 1;

对应的C源代码如下:

2021-07-08 13:49                      mein.c                      Page 1


    1   #include <stdlib.h>
    2   
    3   int main(int argc, char *argv[])
    4   {
    5       const char *const*const a = argv + 1;
    6       return 0;
    7   }

我相信我的声明说a 是一个常量指针,指向一个指向常量字符串的常量指针数组。 我也相信char *argv[]等价于char **argv。

问题是:是我错了,还是 gcc 错了?

【问题讨论】:

  • “虽然真正的程序员不需要const” - “真正的程序员在 0 和 1 中编写所有内容”。我不知道是谁告诉你的,但这是废话。请编写 const 正确的代码。
  • @StefanRiedel 因为“真正的程序员”是一种笑话(从今天的角度来看),所以关于真正的程序员的一切都被认为是一个笑话。或者也许认为我的陈述只是具有讽刺意味。
  • @4386427 显然我没有看到问题所在,也许可以更详细地解释一下。
  • 好的,我明白了。在 SO 上很难区分讽刺和坏心态。
  • @4386427 该站点的主页显示“此超文本页面集合版权所有 1995-2005,由史蒂夫·萨米特所有。”。

标签: c gcc-warning gcc4


【解决方案1】:

对于初始化,C 2018 6.7.9 11 说:

...与简单赋值相同的类型约束和转换适用...

对于简单的分配,6.5.16.1 1 说:

应满足以下条件之一:……左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针, 并且左边指向的类型具有右边指向的类型的所有限定符;…

为此,“左操作数”是a,类型为const char * const * const,“右操作数”是argv + 1,类型为char **。左操作数指向的类型是const char * const,右操作数指向的类型是char *。

左操作数是const char * 的限定版本,右操作数是char * 的非限定版本。如果前一种类型 (const char *) 与后一种类型 (char *) 兼容,则此初始化符合约束。

6.7.6.1 2 说:

对于要兼容的两个指针类型,两者都应具有相同的限定,并且都应是指向兼容类型的指针。

如果const char 和char 兼容,那么const char * 和char * 是兼容的。

6.7.3 11 说:

对于要兼容的两个限定类型,两者都应具有兼容类型的相同限定版本;说明符或限定符列表中类型限定符的顺序不会影响指定的类型。

由于const char 是const 合格而char 不是,因此这些类型不兼容。

因此,这种初始化不符合 C 标准的约束。

问题是:是我错了,还是 gcc 错了?

GCC 是对的,你错了。

【讨论】:

  • 这很难理解:所以本质上是“中间const”导致了问题,但是为什么我不能将一个指针数组分配给一个常量指针数组呢? OTOH char *const *c = argv + 1; 不会导致错误(就像将 char * 分配给 const char * 一样)。
猜你喜欢
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2021-04-15
  • 2020-05-09
  • 1970-01-01
  • 2015-01-04
  • 2016-09-26
  • 2013-12-23
相关资源
最近更新 更多