为什么我会尝试将’char(* c)’传递给期望’const char(* c)’的函数?

我知道char ** vs const char **事情(就像在c faq中描述的那样)但是我看不到任何使用指向数组的指针的情况会导致数组内部的一些内容被实际修改。

我的代码:

 void fun(const char (*p)[6]) { printf("%s", p[0]); } int main(int argc, char *argv[]) { char a[6] = "hello"; char (*c)[6]; c = &a; fun(c); } 

使用gcc编译时给出以下输出:

 test.c:17:9: warning: passing argument 1 of 'fun' from incompatible pointer type test.c:5:10: note: expected 'const char (*)[6]' but argument is of type 'char (*)[6]' 

这里的问题在某种程度上是相关的,但到目前为止还没有答案。 只是编译器是paranoïd并且摆脱警告的唯一方法是显式转换? 或者是否有可能出现问题?

这只是C语言规范的一个怪癖。 再举一个例子,从const-correctness的角度来看, char **const char *const *转换也是安全的,但在C中是禁止的。

这个const-correctness规则的怪癖在C ++语言中是“固定的”,但C在这方面仍然坚持其原始规范。

常规转换由标准的6.5.16.1(1)部分涵盖:

  • 两个操作数都指向兼容类型的限定版或不合格版本的指针,左边指向的类型具有右边指向的所有类型的限定符;

在这种情况下,看起来Tchar [6] ,其余的要求显然成立,通过修改您的示例可以看出:

 int main(int argc, char *argv[]) { typedef char c6[6]; c6 a = "hello"; const c6 *p = &a; } 

然而事实并非如此! 这与6.7.3(8)相交:

如果数组类型的规范包括任何类型限定符,则元素类型是如此合格,而不是数组类型。

所以const c6 *实际上命名为const char (*)[6] ; 也就是指向const char的数组[6]的 指针 ,而不是指向 char的 const数组[6]的指针

然后LHS指向const char[6]类型,RHS指向char[6]类型,它们是不兼容的类型,并且简单赋值的要求不成立。

实际上原因非常相似(char **与数组指针)。

对于你想要做的事情,以下就足够了(并且它有效):

 void fun(const char *p) { printf("%s", p); } int main(int argc, char *argv[]) { char a[6] = "hello"; char *c; c = a; fun(c); } 

根据您的尝试,可以按照以下方式修改值,以达到目的(仅举例):

 void morefun(const char *p[6]) { char d; char *p1 = &d; p[1] = p1; *p1 = 'X'; printf("\nThe char is %c\n", *p[1]); } int main(int argc, char *argv[]) { const char *d[6]; morefun(d); }