簡體   English   中英

無效**作為參數需要強制轉換

[英]Void** as parameter requires cast

我在C中有一個函數,需要接收一個指向數組的指針(具有未指定的類型)。

為此,我使用void **,因為我將使用void *來接收未指定元素的數組。

不幸的是,存在一個問題:編譯器發出警告(從不兼容的指針類型傳遞參數1'f')。 如果我忽略該警告,並嘗試執行該程序,那么一切都會按預期進行。

擺脫警告的唯一方法是將我嘗試傳遞給函數的所有內容強制轉換為void **。

為什么C會那樣表現? 還有解決警告的更好方法嗎?

PS:我需要使用帶有標志-std = gnu89 -pedantic -Wall的GCC進行編譯

int f(void** param){ return 1; }

int main(){
    int *arr = malloc(sizeof(int) * 20);
    int i;
    for(i=0; i < 20; i++) arr[i] = i;
    f(&arr);
}

指向任何類型的指針都是void* ,並且編譯器將不會抱怨對該類型的轉換。 但是void**不是指向任何東西的指針,它是指向任何東西的指針數組的指針,這與指向整數的指針數組的指針有很大的不同,因此編譯器會抱怨。 因此,要解決該警告,是的,您需要顯式強制轉換。

似乎您想修改函數內的數據地址(而不是值),您不能直接使用void *來完成此操作,因為您不能對void *使用算術運算,但是可以傳遞第一元件和字節的塊( char * ),假設要更改的地址arrarr + 1在函數內部(所述陣列的所述第二元素):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void f(void *ptr, size_t size)
{
    // char *p = *ptr;  Wrong, you can't dereference a void * without a cast
    char *p = *(char **)ptr; /* pointer to address of ptr */

    memmove(p, p + size, size); /* assign the address of ptr + 1 to ptr */
}

int main(void)
{
    int *arr = malloc(sizeof(int) * 20);
    int i;
    for (i = 0; i < 20; i++) arr[i] = i;
    f(&arr, sizeof arr[0]);
    printf("%d\n", arr[0]);
    return 0;
}

輸出:

1

盡管void *是C語言中的“通用指針”,但void **不是“指針通用指針”。 相反,它只不過是“指向void * 特定指針,即通用指針”。

在您的情況下, int **隱式轉換為void ** ,這不是通用的。 由於不能保證void **能夠容納所有指針變量(因此與int **不兼容),因此編譯器會發出警告。

這是clang生成的警告:

main.c:7:7: warning: incompatible pointer types passing 'int **' to parameter of
      type 'void **' [-Wincompatible-pointer-types]
    f(&arr);
      ^~~~
main.c:1:14: note: passing argument to parameter 'param' here
int f(void** param){ return 1; }

要消除此警告,可以使用int f(void* param); ,並將param轉換為函數內的int ** 將不會發出警告,因為可以使用void *來存儲任何指針(引自N1570):

6.3.2.3指針

1指向void的指針可以轉換為任何對象類型的指針,也可以將其轉換為任何對象類型的指針。 指向任何對象類型的指針都可以轉換為void指針,然后再返回; 結果應等於原始指針。

暫無
暫無

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

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