簡體   English   中英

從“void (*)()”到“void*”的無效轉換 (C++)

[英]invalid conversion from 'void (*)()' to 'void*' (C++)

我正在學習通用指針void* ,它允許您存儲多種數據類型的地址。 但是,當嘗試存儲 function 的地址時,我需要轉換它,例如:

ptr = (void*)someFunc

而對於原始數據類型,我不需要強制轉換:

ptr = &a

這里的ptr是一個void*指針。

為什么會這樣?

void someFunc(){
    cout << ("hello");
}

int main(){
    int a = 5;
    string b = "Hello boiii";

    void* ptr = &a;

    cout << "ptr holding address of variable a of type int" << endl;
    cout << ptr << endl;

    ptr = &b;
    cout << "ptr holding address of variable b of object string" << endl;
    cout << ptr << endl;

    ptr = (void*)someFunc; // doubt
    cout << "ptr holding address of function someFunc" << endl;
    cout << ptr << endl;

    return 0;
}

您不能將 function 指針分配給類型為c/v void *的指針,前提是實現不有條件地支持此類轉換。 您只能分配一個指向 object 的c/v void *類型的指針。

來自 C++ 14 Standard (4.10 Pointer conversions)

2 “指向 cv T 的指針”類型的純右值,其中 T 是 object 類型,可以轉換為“指向 cv void 的指針”類型的純右值。 將指向 object 類型的指針的非空指針值轉換為“指向 cv void 的指針”的結果表示與原始指針值在 memory 中相同字節的地址。 null 指針值轉換為目標類型的 null 指針值。

8 有條件地支持將 function 指針轉換為 object 指針類型,反之亦然。 這種轉換的含義是實現定義的,除非實現支持雙向轉換,將一種類型的純右值轉換為另一種類型並返回,可能具有不同的 cvqualification,應產生原始指針值。

並來自 C 標准(6.3.2.3 指針)

1 指向 void 的指針可以與指向任何 object 類型的指針相互轉換。 指向任何 object 類型的指針都可以轉換為指向 void 的指針,然后再轉換回來; 結果應與原始指針比較。

8 指向一種類型的 function 的指針可以轉換為指向另一種類型的 function 的指針,然后再轉換回來; 結果應與原始指針比較。 如果轉換后的指針用於調用類型與引用類型不兼容的 function,則行為未定義。

這是標准中管理 function 指針(包括void(*)(void)和 object 指針(例如void* )之間的互換性和轉換)的實際規則:

有條件地支持將 function 指針轉換為 object 指針類型,反之亦然。 這種轉換的含義是實現定義的,除非實現支持雙向轉換,將一種類型的純右值轉換為另一種類型並返回,可能具有不同的 cv 限定,應產生原始指針值。

https://eel.is/c++draft/expr.reinterpret.cast#8

這意味着在某些平台上,轉換可能會被完全拒絕(例如,某些體系結構將代碼和數據保存在不同的 memory 空間中,並且每個空間都需要不同大小的指針),而在可能的平台上,轉換可能會生成如果啟用了此類警告,則會出現可移植性警告。

POSIX 做出一些額外的保證以支持動態加載—— dlsym的返回值可能是 object 或 function 指針,因此在 POSIX 平台上它們之間的轉換必須是可能的。

暫無
暫無

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

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