繁体   English   中英

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;
}

问题是函数参数中的数组“衰减”为类型为const int(*) [10]的指针,这是指向项为const的数组的指针。

此指针类型与从main传递的内容不兼容,因为该数组衰减为int(*)[10]类型的数组指针。

有一个规则“指向类型的指针可以转换为限定指针到类型”。 例如int*含义可以转换为const int*但不是相反。 但是这条规则不适用于此。

因为“指向数组的指针”的限定版本是“const-pointer-to-array”,而不是“指向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;
}

根据错误消息函数,期望指向常量的指针。

typedef int Row[10];

void P(const Row A[])
{
}


int main(void)
{
    const Row A[10];

    P(A);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM