我有一个函数采用静态二维数组并将数组元素的元素视为常量:
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会在这种情况下输出这样的警告。 为什么我的指针/数组不兼容?
答案 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);