gdb中的C++static_cast返回的结果与gcc不同

C++ static_cast in gdb returns different result than gcc

本文关键字:结果 gcc 不同 返回 中的 C++static cast gdb      更新时间:2023-10-16

我正在调查一个问题,当static_casting long double to double时,gcc和gdb的奇怪行为。我有如下代码:

const double xDelta = 60.0;
int xSplits = 3;
const long double xStepL = static_cast<long double>(xSplits) / xDelta;
const double xStep = static_cast<double>(xStepL);

基本上它除以3/60,所以结果应该是0.05。当使用简单的double值进行操作时,xStep的值为0.050000000000000003,因此决定使用更高精度的12字节long double。在上述例子中,xStepL的值为0.05000000000000000000067762635780344。当将该值强制转换回double时,它实际上又是0.050000000000000003。但是,当使用gdb检查值时,它会打印以下内容:

(gdb) p xStep
$1 = 0.050000000000000003
(gdb) p static_cast<double>(xStepL)
$2 = 0.049999999999999996

知道为什么结果不同吗?我真的希望它是第二个。有人知道如何做到这一点吗?

顺便说一句,我使用的是GCC 4.3.4和GDB 7.2.50。

我认为问题是static_casts没有用相同的值进行调用。代码中的值将使用更高精度的寄存器值进行调用,而从gdb调用的值将在内存中使用长双精度。我不确定编译器可以这样做的确切位置,但我猜这是一个——所以答案可能会因帮助而有所不同。

这看起来像是gdb中的一个bug。

long double强制转换为double的指令是fldt(10字节浮点加载)和fstpl(8字节浮点存储)。执行降精度浮点存储时,它将四舍五入操作数,从0.05000000000000000000067762635780344变为0.050000000000000003。看起来gdb正在截断操作数,从0.05000000000000000000067762635780344变为0.049999999999999996。以浮点十六进制表示:

0x1.99999999999999999999ap-5 -> 0x1.999999999999ap-5 (gcc, correct)
0x1.99999999999999999999ap-5 -> 0x1.9999999999999p-5 (gdb, incorrect)

讨论表明,这在gdb(7.4.50)的最新版本中得到了修复。

相关文章: