溢出的原因(G++ vs Clang++)[关闭]

Posted

技术标签:

【中文标题】溢出的原因(G++ vs Clang++)[关闭]【英文标题】:Reason for Overflow (G++ vs Clang++) [closed] 【发布时间】:2020-02-18 20:38:33 【问题描述】:

当我使用 Clang++ 和 G++ 编译以下 C++ 代码时

void ScaleFactor(float32_t scale, int32_t &factor) 
    factor = floor(log2(abs(scale))+1)
    cout << factor << endl;

scale 的值等于 0.234375 并且 factor 通过引用传递给另一个函数中的整数变量,我在使用 GDB 进行调试时得到了 factor 的以下不同输出

(int32_t &) @0x7fffffffdaa0: -2147483648 (Clang++)
(int32_t &) @0x7fffffffda9c: -2 (G++)

但是,在将 abs() 替换为 fabs() 时,每个输出都与所需的输出匹配

(int32_t &) @0x7fffffffdb90: -2 (Clang++)
(int32_t &) @0x7fffffffdddc: -2 (G++)

造成这种差异的原因可能是什么?

【问题讨论】:

你用什么值调用函数? 对不起,忘了说!值比例为 0.234375,因子只是对整数变量的引用。 建议:将程序缩减为ScaleFactor 和一个简单的main,它只存在于使用您的固定输入调用ScaleFactor。如果您得到相同的结果,请发布这个小程序,以便我们都可以运行它并查看。如果问题消失了,yousa 就有了 bug,但这不是 yousa 认为的问题。 float32_t 来自哪里? minimal reproducible example、命令行、警告等在哪里?这是相关的,答案可能取决于您的确切 #include 列表。 【参考方案1】:

请参阅此帖子的 answer。 abs 通常用于整数,fabs 用于浮点类型。不过,abs 的 G++ 实现似乎也可以处理浮点数。

【讨论】:

【参考方案2】:

这段代码是否产生相同的结果?对我来说似乎不是:https://godbolt.org/z/Wj9v6j

#include <iostream>
#include <cmath>

using namespace std;

using float32_t = float;

void ScaleFactor(float32_t scale, int32_t &factor) 
    factor = floor(log2(abs(/*(int)*/scale))+1);
    cout << factor << endl;



int main() 
    int32_t result;
    ScaleFactor(0.234375f, result);
    return 0;

如果没有,您确定这里没有其他问题吗?也许您在使用 clang 构建时包含了 C 版本的数学函数,abs 和 fabs 之间存在差异?

如果我在将 float 传递给 abs 时将它转换为 int 时,你得到的奇怪结果正是我所得到的,这正是你使用 abs 的 C 版本时所期望的结果。

【讨论】:

我再赌 42 美元,当它发生时,留在原处的东西将具有与返回时相同的精确值。 我刚刚拿走了你的上帝螺栓链接,用 math.h 替换了 cmath,删除了所有 iostream 内容,删除了 using namespace stdstd::abs still got called。没想到。期待编译失败(没有int32_t)。不知道发生了什么。 好吧。那很简单。 math.h 里面是一个# include &lt;cmath&gt;。可能在某处包含一个 cstdint。

以上是关于溢出的原因(G++ vs Clang++)[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

自动模板参数:g ++ 7.3 vs clang ++ 6.0:哪个编译器正确?

Clang vs GCC - 产生更快的二进制文件? [关闭]

windows环境下gcc/g++ 编译器 乱码问题解决

vs2017编译项目报错:Microsoft.Cpp.Clang.targets(212,5): error MSB6006 处理方法

vs2017编译项目报错:Microsoft.Cpp.Clang.targets(212,5): error MSB6006 处理方法

clang-format:如果语句溢出,则强制参数和参数为一行