c++ - 将指针传递给结构,对比传递 void 指针并强制转换为结构

标签 c++

我正在处理具有这种模式的遗留代码库:

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 传递或传递到第 3 方库;它完全保留在我们拥有的 C++ 代码中。

最佳答案

这通常不是一个好的选择,但我知道这真正有意义的唯一情况是如果你想在不使用模板的情况下将有状态回调传递给函数:

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

基本上要点是,因为您没有使用模板,所以您必须修复您接受的函数签名(当然,它可以而且经常接受其他参数并返回一些东西)。但是,如果您只是使用自己的参数调用该函数,则该函数只能通过全局变量在调用之间保持状态。因此,takes_callback 的合约 promise 以 data 作为参数调用 f

因此,如果您想在此类 API 中使用 some_method 作为回调,您必须让它采用 void*,并在内部进行转换。显然,你在这里抛弃了类型安全,如果你碰巧用 &somemethod 和指向任何不是 sometype_t 的指针调用 takes_callback 你有UB。

拥有 C ABI 是避免使用模板的原因之一,但不是唯一的原因。也许他们担心代码膨胀,或者想将实现保留在 .so 中,以便可以在不重新编译的情况下升级版本,等等。

关于c++ - 将指针传递给结构,对比传递 void 指针并强制转换为结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45024092/

相关文章:

c++ - is_assignable 和 std::unique_ptr

c++ - 如果键不存在,为什么 std::map operator[] 会创建一个对象?

c++ - 如何在预编译后通过查看文件来调试Boost?

c++ - 使用tinyxml创建xmlns

c++ - 在Qt中QFileDialog setsuffix在Linux中不起作用,如何解决?

c++ - 函数指针 + 映射 + 迭代器 + 类

c++ - 如何将像素格式 AV_PIX_FMT_CUDA 的 FFmpeg AVFrame 转换为像素格式 AV_PIX_FMT_RGB 的新 AVFrame

c++ - 将 5x5 矩阵减少到 c 中的 25 元素数组

c++ - react native 0.40.0 : Ordered comparison between pointer and zero ('NSNumber *' and 'int' )

c++ - 为 GLUT 创建自定义窗口?