不兼容的指针类型和常量

Incompatible pointer types and constness

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

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]);

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

当使用 clang 编译 -pedantic-errors-Wall 时,我没有收到任何关于指针不兼容的警告。

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

来自 C-FAQ [Question 11.10]

In C, if you must assign or pass pointers which have qualifier mismatches at other than the first level of indirection, you must use explicit casts (e.g. (const char **) in this case), although as always, the need for such a cast may indicate a deeper problem which the cast doesn't really fix.

你的情况:

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

GCC 符合标准,Clang 是错误的。

6.3.2.3/2:

For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type;

看起来很有前途。但是等一下。

6.2.5/26:

A derived type is not qualified by the qualifiers (if any) of the type from which it is derived

标准中专门针对数组的这一规定是没有必要的,而且可以很容易地撤销。也就是说,const char[3] 可以很容易地成为 char[3] 的 const 限定版本。但事实并非如此。它们只是不同的、不兼容的类型。事实上,C 中根本没有 const 限定的数组类型,所以你不能有 char[3] 的 const 限定版本。这是我们的标准,必须遵守。