首页 > 解决方案 > 如果这是未定义的行为,那么为什么将其作为看似合理的示例给出呢?

问题描述

在一篇关于类型双关语的维基百科文章中,它给出了一个将 int 类型指针指向浮点数以提取有符号位的示例:

但是,假设浮点比较是昂贵的,并且假设浮点是根据 IEEE 浮点标准表示的,并且整数是 32 位宽,我们可以进行类型双关以提取浮点的符号位仅使用整数运算的数字:

bool is_negative(float x) {
    unsigned int *ui = (unsigned int *)&x;
    return *ui & 0x80000000;
}

将指针指向不是它自己的类型是未定义的行为,这是真的吗?这篇文章使这种操作看起来像是合法且普遍的事情。在这段特定的代码中可能会出错的地方是什么?我对 C 和 C++ 都感兴趣,如果它有什么不同的话。两者都有严格的别名规则,对吧?

标签: c++ctype-punning

解决方案


将指针指向不是它自己的类型是未定义的行为,这是真的吗?

不,C 和 C++ 都允许将对象指针转换为不同的指针类型,但有一些注意事项。

但除了少数例外,通过不同类型的指针访问指向的对象确实具有未定义的行为。这种未定义的行为源于评估*ui示例函数中的表达式。

这篇文章使这种操作看起来像是合法且普遍的事情。在这段特定的代码中可能会出错的地方是什么?

行为是未定义的,因此程序可以做的任何事情都是可能的。在实践中,观察到的行为可能正是维基百科文章的作者所期望的,如果不是,那么最可能的不当行为是计算错误结果的函数的变化。

我对 C 和 C++ 都感兴趣,如果它有什么不同的话。两者都有严格的别名规则,对吧?

据我所知,示例代码在 C 和 C++ 中都有未定义的行为,原因基本相同。


推荐阅读