将2D数组作为指针传递,gcc警告不兼容指针类型

将2D数组作为指针传递,gcc警告不兼容指针类型,c,arrays,pointers,gcc,C,Arrays,Pointers,Gcc,我有以下将2D数组作为指针传递的版本 版本1 版本2 版本1警告不兼容的指针类型。应为int*[5],但参数的类型应为int*。但是,版本2使用指针调用同一函数在编译时没有任何此类警告 gcc选项:gcc-O0-g3-Wall-c-fmessage length=0 是否有人可以对此进行说明?如果在分配函数指针时删除强制转换: tmp.c: In function ‘main’: tmp.c:13:22: warning: initialization from incompatible poi

我有以下将2D数组作为指针传递的版本

版本1

版本2

版本1警告不兼容的指针类型。应为int*[5],但参数的类型应为int*。但是,版本2使用指针调用同一函数在编译时没有任何此类警告

gcc选项:gcc-O0-g3-Wall-c-fmessage length=0


是否有人可以对此进行说明?

如果在分配函数指针时删除强制转换:

tmp.c: In function ‘main’:
tmp.c:13:22: warning: initialization from incompatible pointer type [enabled by default]
     callDisplay fn = &disp;
即使通过强制转换到不同类型的函数指针,您在调用函数指针时调用了未定义的行为,强制转换也会抑制此警告。基本上,您不需要强制转换函数指针,因为它将隐藏任何类似这样的警告

如果修复函数指针,则会得到以下代码:

typedef void(*callDisplay)(int[][5]);

void disp(int a[][5])
{
    printf("a[0][3] = %d\n", a[0][3]); /* a[0][3] = 4 */
}

int main ()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    callDisplay fn = &disp;
    fn(a);
    return 0;
}
编译时,您会收到与第一个示例相同的警告:

tmp.c: In function ‘main’:
tmp.c:14:5: warning: passing argument 1 of ‘fn’ from incompatible pointer type [enabled by default]
     fn(a);
     ^
tmp.c:14:5: note: expected ‘int (*)[5]’ but argument is of type ‘int *’

如果在分配函数指针时删除强制转换,则会得到:

tmp.c: In function ‘main’:
tmp.c:13:22: warning: initialization from incompatible pointer type [enabled by default]
     callDisplay fn = &disp;
即使通过强制转换到不同类型的函数指针,您在调用函数指针时调用了未定义的行为,强制转换也会抑制此警告。基本上,您不需要强制转换函数指针,因为它将隐藏任何类似这样的警告

如果修复函数指针,则会得到以下代码:

typedef void(*callDisplay)(int[][5]);

void disp(int a[][5])
{
    printf("a[0][3] = %d\n", a[0][3]); /* a[0][3] = 4 */
}

int main ()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    callDisplay fn = &disp;
    fn(a);
    return 0;
}
编译时,您会收到与第一个示例相同的警告:

tmp.c: In function ‘main’:
tmp.c:14:5: warning: passing argument 1 of ‘fn’ from incompatible pointer type [enabled by default]
     fn(a);
     ^
tmp.c:14:5: note: expected ‘int (*)[5]’ but argument is of type ‘int *’

此函数声明

typedef void(*callDisplay)(int*);
调用like时具有兼容的参数

fn(a);
问题与此铸造有关

callDisplay fn = (callDisplay) &disp;
这是错误的

即程序具有未定义的行为

根据C标准6.3.2.3指针

8指向一种类型函数的指针可以转换为指向 另一种类型的函数,然后再返回;结果应进行比较 等于原始指针。如果转换的指针用于 调用类型与引用类型不兼容的函数, 该行为未定义


此函数声明

typedef void(*callDisplay)(int*);
调用like时具有兼容的参数

fn(a);
问题与此铸造有关

callDisplay fn = (callDisplay) &disp;
这是错误的

即程序具有未定义的行为

根据C标准6.3.2.3指针

8指向一种类型函数的指针可以转换为指向 另一种类型的函数,然后再返回;结果应进行比较 等于原始指针。如果转换的指针用于 调用类型与引用类型不兼容的函数, 该行为未定义