首页 > 解决方案 > 声明和初始化一个完全的`const``char *argv[]`

问题描述

我尝试将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 错了?

标签: cgcc-warninggcc4

解决方案


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

…与简单赋值相同的类型约束和转换适用…</p>

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

以下其中一项应成立:……左操作数具有原子、合格或非限定指针类型,并且(考虑到左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的合格或非限定版本的指针,并且左侧指向的类型具有右侧指向的类型的所有限定符;…</p>

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

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

6.7.6.1 2 说:

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

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

6.7.3 11 说:

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

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

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

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

GCC 是对的,你错了。


推荐阅读