GCC 发出不兼容指针类型的警告
GCC issues warning of incompatible pointer type
当我用 GCC 4.9.2 编译下面的程序时,我收到以下警告:从不兼容的指针类型 传递‘P’的参数 1。但是,我没有发现该程序有任何问题。有什么线索吗?
typedef int Row[10];
void P(const Row A[])
{
}
int main(void)
{
Row A[10];
P(A);
return 0;
}
这是从 GCC 到 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
.
进行了干净的编译
去掉 typedef,它应该会变得更清晰一点:
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(A);
return 0;
}
问题是函数参数"decays"中的数组变成了const int(*) [10]
类型的指针,也就是指向项为const
的数组的指针。
此指针类型与您从 main 传递的内容不兼容,因为该数组衰减为 int(*)[10]
.
类型的数组指针
有一条规则"pointer-to-type may be converted to qualified-pointer-to-type"。意思是例如 int*
可以转换为 const int*
但不是相反。但这条规则在这里不适用。
因为 "pointer-to-array" 的合格版本是 "const-pointer-to-array",而不是 "pointer-to-const-array",这是你这里的。
不幸的是,这是 C 语言中的一个弱点:使用数组指针时无法获得 const 正确性。唯一的解决方案是一个非常丑陋的解决方案:
P( (const int(*)[10]) A);
对于这种情况,最好完全跳过 const 正确性,以提高可读性。
编辑:在 C11 中,您可以这样做,类型更安全,但它仍然依赖于调用者执行转换:
#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 4.9.2 编译下面的程序时,我收到以下警告:从不兼容的指针类型 传递‘P’的参数 1。但是,我没有发现该程序有任何问题。有什么线索吗?
typedef int Row[10];
void P(const Row A[])
{
}
int main(void)
{
Row A[10];
P(A);
return 0;
}
这是从 GCC 到 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
.
去掉 typedef,它应该会变得更清晰一点:
void P (const int A [][10])
{
}
int main(void)
{
int A[10][10];
P(A);
return 0;
}
问题是函数参数"decays"中的数组变成了const int(*) [10]
类型的指针,也就是指向项为const
的数组的指针。
此指针类型与您从 main 传递的内容不兼容,因为该数组衰减为 int(*)[10]
.
有一条规则"pointer-to-type may be converted to qualified-pointer-to-type"。意思是例如 int*
可以转换为 const int*
但不是相反。但这条规则在这里不适用。
因为 "pointer-to-array" 的合格版本是 "const-pointer-to-array",而不是 "pointer-to-const-array",这是你这里的。
不幸的是,这是 C 语言中的一个弱点:使用数组指针时无法获得 const 正确性。唯一的解决方案是一个非常丑陋的解决方案:
P( (const int(*)[10]) A);
对于这种情况,最好完全跳过 const 正确性,以提高可读性。
编辑:在 C11 中,您可以这样做,类型更安全,但它仍然依赖于调用者执行转换:
#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;
}