将空*参数转换为各种类型的参数是UB吗?
Is it UB to cast void* param to various types?
void WorkHorse(void* ptr, int tag) {
if (SomeFunction(tag)) {
Foo* foo_ptr = (Foo*)ptr;
// do stuff
} else {
Bar* bar_ptr = (Bar*)ptr;
}
}
我知道这通常是一个糟糕的设计,但很好奇它在技术上是否是 UB。
void* 参数转换为各种类型的参数是 UB 吗?
否,将void*
强制转换为指向对象类型的指针不是 UB。如果是这样,那么void*
将几乎毫无用处。
但是,在某些情况下,通过转换后的指针进行间接可能是 UB;通常是当地址不包含适当类型的对象时。
正如你所指出的,使用这样的void*
通常是糟糕的设计,只有在与某些 C API 交互时才需要。
你代码中最让我讨厌的部分是转换的风格,而不是对转换所做的。我宁愿使用static_cast
而不是 C 样式的演员表。使用足以完成预期作业的最弱工具,为编译器指出可疑代码(即关于可能的错误发出警告(提供了最大的回旋余地。
使用static_cast
的一个附带好处是,您的问题的答案直接位于static_cast转化页面@cppreference.com 上。查看第 10 点,该点以以下内容结尾。
将任何指针转换为指向 void 的指针,然后再转换回指向原始(或更多符合 cv 条件(类型的指针,将保留其原始值。
如果您已将Foo*
转换为void*
以获取作为ptr
传入的值,则static_cast
返回到Foo*
将恢复原始值。取消引用原始值是可以的,只要它没有成为悬而未决的指针。
为了公平对待 C 型转换,在这种情况下,使用 C 样式转换或static_cast
时,您确实会得到相同的结果。您可以从显式投射页面 @ cppreference.com 开始获取文档 - 因为该页面链接到static_cast页面。;)
此外,除非 API 要求,否则不要执行这些转换。似乎在这一点上是一致的,所以对我来说只是一个脚注。
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 将空*参数转换为各种类型的参数是UB吗?
- 模板对象的C 数组:施放到常见的非类型模板参数是UB吗?