簡體   English   中英

將指針傳遞給struct,與傳遞void指針並強制轉換為struct

[英]Passing pointer to struct, vs. passing void pointer and casting to struct

我正在使用具有以下模式的舊式代碼庫:

struct sometype_t { /* ... */ };

int some_method(void *arg1) { // void pointer
    ((sometype_t*)arg1)->prop1; // cast
}

是否有任何(常見)方案使用sometype_t *而不是void *是不安全的?

int some_method(sometype_t *arg1) {
    arg1->prop1;
}

指針不會跨ABI傳遞或傳遞給第三方庫。 它完全保留在我們擁有的C ++代碼中。

通常,這不是一個好選擇,但是我知道真正有意義的唯一情況是,如果您希望將有狀態回調傳遞給函數,而不使用模板:

void takes_callback(void(*f)(void*), void * data);

基本上,要點是,由於您不使用模板,因此必須修復您接受的函數簽名(當然,它可以並且經常確實接受其他參數並返回某些內容)。 但是,如果僅使用自己的參數調用該函數,則該函數只能通過全局變量保持兩次調用之間的狀態。 因此, takes_callback承諾以data作為參數調用f

因此,如果您想在這種API中使用some_method作為回調,則必須使其采用void* ,並在內部進行轉換。 顯然,您在這里丟棄了類型安全性,並且如果碰巧使用&somemethod和指向不是sometype_t任何東西的指針調用takes_callback ,則您擁有UB。

擁有C ABI是避免使用模板的原因之一,但這不是唯一的原因。 也許他們擔心代碼膨脹,或者想要將實現保留在.so中,以便無需重新編譯即可升級版本等。

立即想到的顯而易見的常見場景是C標准庫中某些函數的回調。

例如,為std::qsort編寫比較回調的正確方法是用兩個const void *參數聲明該函數,然后將它們強制轉換為回調內的特定指針類型。

用特殊類型的指針替換這些const void *參數只會阻止代碼編譯。

暫無
暫無

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

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