c - 声明和初始化一个完全的`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 错了?
解决方案
对于初始化,C 2018 6.7.9 11 说:
…与简单赋值相同的类型约束和转换适用…</p>
对于简单的分配,6.5.16.1 1 说:
以下其中一项应成立:……左操作数具有原子、合格或非限定指针类型,并且(考虑到左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的合格或非限定版本的指针,并且左侧指向的类型具有右侧指向的类型的所有限定符;…</p>
为此,“左操作数”是a
with 类型const char * const * const
,“右操作数”是argv + 1
with 类型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 是对的,你错了。
推荐阅读
- python-3.x - 根据输入返回 pandas groupby
- android - 反应本机应用程序图像渲染不起作用
- python - 如何在文本文件中使用正则表达式查找字符串的计数?
- c++ - QLineEdit:显示已处理的文本,而不是输入的文本,但保留它(自定义回显模式)
- live-streaming - 即使视频暂停,m3u8 清单也会继续下载
- php - Laravel 运行时异常 (1/1)
- c# - groupby LINQ C# 之后的 Oorderby(没有 lambda)
- mongodb - 子文档中的 Mongoose 聚合管道连接字段
- android - 如何将 android 应用流量转换为代理和解密 TLS 流量?
- ios - 从 iPad Pro 使用 GCP