GCC issues warning of incompatible pointer type

你说的曾经没有我的故事 提交于 2020-01-03 17:49:31

问题


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

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[])
      ^

Edit: The program compiles cleanly with Clang 3.5.0 and the options -pedantic -std=c89 -Wall.


回答1:


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

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.

This pointer type is not compatible with what you pass from main, because that array decays into an array pointer of type int(*)[10].

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.

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.

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

It might be better to skip const correctness completely for cases like this, in favour of readability.


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



回答2:


According to the error message function expect a pointer to a constant.

typedef int Row[10];

void P(const Row A[])
{
}


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

    P(A);
    return 0;
}


来源:https://stackoverflow.com/questions/41180809/gcc-issues-warning-of-incompatible-pointer-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!