将指针传递到结构,与传递 void 指针并强制转换为结构
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 传递或传递到第 3 方库中;它完全保留在我们拥有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 *
参数替换为特定类型的指针只会阻止代码编译。
相关文章:
- 如何在 C# 中映射双 C 结构指针?
- C++:映射结构中的结构指针
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 类的静态结构指针声明在C++
- 在两个.cpp文件之间定义全局类/结构指针
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 是否可以将无符号字符数组reinterpret_cast到仅包含C++中无符号字符成员的结构指针
- 如何在地图中使用结构指针
- 结构指针在"新"调用上给出已分配的地址?
- 铸造结构指针指向C 的工会指针
- c++ 结构指针在初始化为 NULL 时无法读取内存
- 函数中的结构指针的地址为0x1
- C 用结构指针初始化结构
- C 结构指针铸成数组Interop C#
- 方法中不允许访问结构指针
- 如何打印出结构指针
- MPI_Op_create:候选功能不可行.自定义结构指针不能解释为空指针
- 尝试将结构指针传递给类时出错
- 初始化结构指针的值
- 使用 pybind11 将自定义结构(指针向量)从 C++ 传递到 python 的方法是什么?