簡體   English   中英

將2D數組作為指針傳遞,gcc警告不兼容的指針類型

[英]Passing 2D array as pointer, gcc warning incompatible pointer type

我有以下版本的將2D數組作為指針傳遞。

版本1

#include <stdio.h>  

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};
    disp(a);
    return 0;
}

版本2

#include <stdio.h>

typedef void(*callDisplay)(int*);

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 = (callDisplay) &disp;
    fn(a);
    return 0;
}

版本1發出警告incompatible pointer type. expected int (*)[5] but argument is of type int * incompatible pointer type. expected int (*)[5] but argument is of type int *為預期的incompatible pointer type. expected int (*)[5] but argument is of type 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 *’

此函數聲明

typedef void(*callDisplay)(int*);

具有兼容的參數,當被稱為

fn(a);

問題與此鑄造有關

callDisplay fn = (callDisplay) &disp;

這是錯誤的。

那是程序具有不確定的行為。

根據C標准(6.3.2.3指針)

8指向一種類型的函數的指針可以轉換為指向另一種類型的函數的指針,然后再返回; 結果應等於原始指針。 如果使用轉換后的指針來調用其類型與引用的類型不兼容的函數,則該行為是不確定的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM