GCC发出警告,指出指针类型不兼容 [英] GCC issues warning of incompatible pointer type
问题描述
当我使用GCC 4.9.2编译以下程序时,收到以下警告:从不兼容的指针类型传递"P"的参数1 .但是,我看不到程序有什么问题.有任何线索吗?
When I compile the program below with GCC 4.9.2 I get the following warning: passing argument 1 of ‘P’ from incompatible pointer type. However, I don't see anything wrong with the program. Any clues?
typedef int Row[10];
void P(const Row A[])
{
}
int main(void)
{
Row A[10];
P(A);
return 0;
}
这是从GCC到stderr的完整输出:
Here is the complete output from GCC to stderr:
test.c: In function ‘main’:
test.c:12:4: warning: passing argument 1 of ‘P’ from incompatible pointer type
P(A);
^
test.c:3:6: note: expected ‘const int (*)[10]’ but argument is of type ‘int (*)[10]’
void P(const Row A[])
^
程序使用Clang 3.5.0和选项-pedantic -std=c89 -Wall
干净地编译.
The program compiles cleanly with Clang 3.5.0 and the options -pedantic -std=c89 -Wall
.
推荐答案
摆脱typedef,它应该变得更加清晰:
Get rid of the typedef and it should become a little bit clearer:
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(A);
return 0;
}
问题在于函数参数中的数组衰减"为类型为const int(*) [10]
的指针,该指针是指向项目为const
的数组的指针.
The problem is that the array in the function parameter "decays" into a pointer of type const int(*) [10]
, which is a pointer to an array where the items are const
.
此指针类型与您从main传递的指针类型不兼容,因为该数组会衰减为类型为int(*)[10]
的数组指针.
This pointer type is not compatible with what you pass from main, because that array decays into an array pointer of type int(*)[10]
.
有一个规则指针类型可以转换为合格的指针类型".例如,int*
的含义可以转换为const int*
,但反之则不行.但是该规则不适用于这里.
There is a rule of "pointer-to-type may be converted to qualified-pointer-to-type". Meaning for example int*
may be converted to const int*
but not the other way around. But that rule does not apply here.
因为指针数组"的合格版本是"const-pointer-to-array",而不是"pointer-to-const-array",这就是您在此处使用的.
Because the qualified version of "pointer-to-array" is "const-pointer-to-array", and not "pointer-to-const-array", which is what you have here.
不幸的是,这是C语言的一个弱点:使用数组指针时不能保持const正确性.唯一的解决方案是一个非常丑陋的解决方案:
Unfortunately this is a weakness in the C language: you cannot have const correctness while using array pointers. The only solution is a very ugly one:
P( (const int(*)[10]) A);
在这种情况下,最好完全跳过const正确性,以提高可读性.
It might be better to skip const correctness completely for cases like this, in favour of readability.
在C11中,您可以这样做,这是更安全的类型,但是它仍然依赖于调用方执行强制转换:
In C11 you can do like this, which is more type safe but it still relies on the caller performing a cast:
#define const_array_cast(arr, n) _Generic(arr, int(*)[n] : (const int(*)[n])arr )
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(const_array_cast(A,10));
return 0;
}
这篇关于GCC发出警告,指出指针类型不兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!