为何g++未对代码中的(s/s)除法操作进行优化移除?
为什么g++编译器未对代码中的(s/s)除法操作进行优化移除?
主要有两个核心原因:
- 浮点数精度的不确定性:s是
unsigned类型,转成float时,当s的数值超过float的精确整数表示范围(即大于2^24,单精度浮点数的尾数仅有24位有效数字),转换后的浮点数会被舍入近似。虽然相同近似值相除看起来结果是1.0,但编译器必须严格遵循C++语义,不能保证所有场景下这个除法的结果都是精确的1.0。 - 参数取值的未知性:你使用了
-fno-inline编译,模板函数numbbo会被编译成独立的函数而非内联到main中。此时编译器无法预知调用该函数时会传入什么值:比如若传入s=0,static_cast<float>(0)/static_cast<float>(0)会得到NaN,彻底改变表达式结果。编译器不能假设调用者只会传入非0且能被float精确表示的s,因此必须保留除法操作以保证语义正确。
另外,即使去掉-fno-inline让函数内联,编译器看到main中传入的argc(至少为1),仍可能因float转换的精度问题不直接将(s/s)替换为1.0——因为argc理论上可以大到超出float的精确表示范围,此时转换后的除法结果并非严格的1.0,编译器必须保证计算结果符合浮点数语义。
内容的提问来源于stack exchange,提问作者gustavo
相关产品推荐
相关产品推荐

