c++ - 如果这是未定义的行为,那么为什么将其作为看似合理的示例给出呢?
问题描述
在一篇关于类型双关语的维基百科文章中,它给出了一个将 int 类型指针指向浮点数以提取有符号位的示例:
但是,假设浮点比较是昂贵的,并且假设浮点是根据 IEEE 浮点标准表示的,并且整数是 32 位宽,我们可以进行类型双关以提取浮点的符号位仅使用整数运算的数字:
bool is_negative(float x) { unsigned int *ui = (unsigned int *)&x; return *ui & 0x80000000; }
将指针指向不是它自己的类型是未定义的行为,这是真的吗?这篇文章使这种操作看起来像是合法且普遍的事情。在这段特定的代码中可能会出错的地方是什么?我对 C 和 C++ 都感兴趣,如果它有什么不同的话。两者都有严格的别名规则,对吧?
解决方案
将指针指向不是它自己的类型是未定义的行为,这是真的吗?
不,C 和 C++ 都允许将对象指针转换为不同的指针类型,但有一些注意事项。
但除了少数例外,通过不同类型的指针访问指向的对象确实具有未定义的行为。这种未定义的行为源于评估*ui
示例函数中的表达式。
这篇文章使这种操作看起来像是合法且普遍的事情。在这段特定的代码中可能会出错的地方是什么?
行为是未定义的,因此程序可以做的任何事情都是可能的。在实践中,观察到的行为可能正是维基百科文章的作者所期望的,如果不是,那么最可能的不当行为是计算错误结果的函数的变化。
我对 C 和 C++ 都感兴趣,如果它有什么不同的话。两者都有严格的别名规则,对吧?
据我所知,示例代码在 C 和 C++ 中都有未定义的行为,原因基本相同。
推荐阅读
- flask-sqlalchemy - 将isolation_level添加到apache mod_wsgi服务器上的flask-sqlalchemy应用程序后,图像中出现间歇性500内部服务器错误
- node.js - Express 服务器不接收请求,http 模块服务器接收
- angularjs - 如何从应用程序洞察请求的响应中删除服务器标头(angular-applicationinsights 库)
- javascript - 如何在 Node.js 中使用新数据重新加载页面
- spring-boot - Spring Boot + Sockjs 客户端离线连接问题
- r - 使用 RTweet 的 search_tweets() 函数在 Twitter 上搜索新推文
- python - 添加按钮后 Tkinter 框架消失
- shopify - 在文章上显示产品
- javascript - 重新加载页面时,文件在 Internet Explorer 中自动下载。如何解决这个问题?
- ruby-on-rails - 无法通过关联更新:找不到记录