声明并初始化一个完全 `const` `char *argv[]`
Declaring and initializing a completely `const` `char *argv[]`
我尝试将 argv
值分配给常量指针,相信将非常量分配给常量变量是安全的。
不幸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 说:
… the same type constraints and conversions as for simple assignment apply…
对于简单赋值,6.5.16.1 1 表示:
One of the following shall hold: … the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;…
为此,“左操作数”是类型为 const char * const * const
的 a
,“右操作数”是类型为 char **
的 argv + 1
。左操作数指向的类型是const char * const
,右操作数指向的类型是char *
.
左操作数是 const char *
的限定版本,右操作数是 char *
的非限定版本。那么如果前者类型(const char *
)兼容后者(char *
),那么这个初始化就符合约束。
6.7.6.1 2 说:
For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
所以 const char *
和 char *
是兼容的,如果 const char
和 char
是兼容的。
6.7.3 11 说:
For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type.
因为 const char
是 const
合格的而 char
不是,所以这些是不兼容的类型。
因此,这个初始化不符合C标准的约束。
The question is: Am I wrong, or is gcc wrong?
GCC 是对的,你错了。
我尝试将 argv
值分配给常量指针,相信将非常量分配给常量变量是安全的。
不幸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 说:
… the same type constraints and conversions as for simple assignment apply…
对于简单赋值,6.5.16.1 1 表示:
One of the following shall hold: … the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;…
为此,“左操作数”是类型为 const char * const * const
的 a
,“右操作数”是类型为 char **
的 argv + 1
。左操作数指向的类型是const char * const
,右操作数指向的类型是char *
.
左操作数是 const char *
的限定版本,右操作数是 char *
的非限定版本。那么如果前者类型(const char *
)兼容后者(char *
),那么这个初始化就符合约束。
6.7.6.1 2 说:
For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
所以 const char *
和 char *
是兼容的,如果 const char
和 char
是兼容的。
6.7.3 11 说:
For two qualified types to be compatible, both shall have the identically qualified version of a compatible type; the order of type qualifiers within a list of specifiers or qualifiers does not affect the specified type.
因为 const char
是 const
合格的而 char
不是,所以这些是不兼容的类型。
因此,这个初始化不符合C标准的约束。
The question is: Am I wrong, or is gcc wrong?
GCC 是对的,你错了。