不兼容的指针类型和常量

时间:2015-02-24 16:42:16

标签: c pointers

我有一个函数采用静态二维数组并将数组元素的元素视为常量:

void test_function(const char arr[3][3]);

我试图调用如下函数:

char my_var[3][3] = { {0, 0, 0}, {0, 0, 0}, {0, 0, 0} };
test_function(my_var);

使用gcc编译(没有任何标志)时,我收到以下警告:

test.c:9:8: warning: passing argument 1 of 'test_function' from incompatible pointer type
   test_function(my_var);
                 ^
test.c:4:6: note: expected 'const char (*)[3]' but argument is of type 'char (*)[3]'
 void test_function(const char arr[3][3]);

如果我从const的原型中移除test_function,警告就会消失。但这并不是我想要的。

使用-pedantic-errors-Wall的clang进行编译时,我不会收到有关指针不兼容的警告。

我只是想了解为什么gcc会在这种情况下输出这样的警告。 为什么我的指针/数组不兼容?

2 个答案:

答案 0 :(得分:11)

海湾合作委员会对标准的字母是正确的,而且Clang错了。

6.3.2.3/2:

  

对于任何限定符 q ,指向非q限定类型的指针可能会转换为指向 q - 该类型的限定版本的指针;

看起来很有前途。但坚持下去。

6.2.5 / 26:

  

派生类型不是由派生类型的限定符(如果有)限定的

这种专门用于阵列的标准规定不是必需的,可以很容易地逆转。也就是说,const char[3]可以很容易地成为char[3]的const限定版本。但事实并非如此。它们只是不同的,不兼容的类型。事实上,C中根本没有const限定的数组类型,因此您不能拥有char[3]的const限定版本。这是我们必须遵守的标准。

答案 1 :(得分:6)

来自C-FAQ [Question 11.10]

  

在C中,如果必须指定或传递具有限定符的指针   您必须使用除第一级间接之外的不匹配   显式转换(例如,在这种情况下为(const char **)),尽管如此   总是,对这种演员表的需要可能表明更深层次的问题   演员表并没有真正解决。

在你的情况下:

test_function((const char (*)[3])my_var);