GCC发出不兼容指针类型的警告

时间:2016-12-16 09:11:44

标签: c gcc gcc-warning

当我使用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完全编译。

2 个答案:

答案 0 :(得分:7)

摆脱typedef,它应该变得更加清晰:

const int(*) [10]

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

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

有一个规则“指向类型的指针可以转换为限定指针到类型”。示例const int*的含义可能会转换为P( (const int(*)[10]) A); ,但不能转换为#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; } 。但是这条规则不适用于此。

因为“指向数组的指针”的限定版本是“const-pointer-to-array”,而不是“指向const-array的指针”,这就是你所拥有的。

不幸的是,这是C语言的一个弱点:使用数组指针时,不能使用const正确性。唯一的解决方案是非常难看的:

g++ -isystem ../include -g -Wall -Wextra -pthread -c ../samples/sample1.cc
g++ -isystem ../include -g -Wall -Wextra -pthread -c ../samples/sample1_unittest.cc
g++ -isystem ../include -I.. -g -Wall -Wextra -pthread -c \
            ../src/gtest-all.cc
In file included from ../src/gtest-all.cc:45:0:
../src/gtest-port.cc: In constructor 'testing::internal::Mutex::Mutex()':
../src/gtest-port.cc:242:45: error: cannot convert 'CRITICAL_SECTION* {aka _CRITICAL_SECTION*}' to '_RTL_CRITICAL_SECTION*' in initialization
       critical_section_(new CRITICAL_SECTION) {
                                             ^
[...]
        Makefile:57: recipe for target 'gtest-all.o' failed
        mingw32-make: *** [gtest-all.o] Error 1

对于这样的情况,最好完全跳过const正确性,这有利于可读性。

编辑:在C11中你可以这样做,这更安全,但仍然依赖于调用者执行演员:

from datetime import datetime

my_date = datetime.strptime('12 Dec 2016', '%d %b %Y')

答案 1 :(得分:-1)

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

typedef int Row[10];

void P(const Row A[])
{
}


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

    P(A);
    return 0;
}