[英]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.