32 位有符号整数除法在 PowerPC 上给出 0x7fffffff 作为商
32 bit signed integer division gives 0x7fffffff as quotient on PowerPC
我正在调试用 C 编写的生产代码,其最简单的形式可以显示为 -
void
test_fun(int sr)
{
int hr = 0;
#define ME 65535
#define SE 256
sr = sr/SE; <-- This should yield 0
if(sr == 1)
hr = ME;
else
hr = (ME+1)/sr; <-- We should crash here.
}
我们将 sr
作为 128 传递,理想情况下应该在处理器中产生被零除错误。我看到这个除法成功地发生了,商为 0x7ffffffff(hr
是这个值)。
当我编译并且 运行 在带有 gcc 的英特尔平台上时,这不会发生(尝试除以零时它会崩溃)。
想知道这个大商背后的原理。不确定这是否只是我还需要发现的其他错误。
有人可以帮我开发另一个具有相同功能的程序吗?
除以零是undefined behaviour, see C11 standard 6.5.5#5(终稿)。
获得陷阱或 SIGFPE 只是 CPU/OS 的礼貌。作为典型 RISC CPU 的 PowerPC 不会捕捉到它,因为它可以通过在进行实际除法之前对除数进行简单检查来安全地检测到。 x86 OTOH 确实 捕捉到这个 - 典型的 CISC 行为。
如果更高层标准要求,您可能错过了自动发出此检查的编译器选项。 POSIX 例如不强制执行 SIGFPE,这是可选的。
根据 PPC 体系结构手册(您可以从 IBM 获得),在 PPC 上除以 0 不会产生任何类型的信号或陷阱;相反,您只会得到一些因处理器而异的未定义值。在您的情况下,它看起来是您在将正数除以 0 时生成 MAXINT(最大正整数)的特定 PPC 变体。
我正在调试用 C 编写的生产代码,其最简单的形式可以显示为 -
void
test_fun(int sr)
{
int hr = 0;
#define ME 65535
#define SE 256
sr = sr/SE; <-- This should yield 0
if(sr == 1)
hr = ME;
else
hr = (ME+1)/sr; <-- We should crash here.
}
我们将 sr
作为 128 传递,理想情况下应该在处理器中产生被零除错误。我看到这个除法成功地发生了,商为 0x7ffffffff(hr
是这个值)。
当我编译并且 运行 在带有 gcc 的英特尔平台上时,这不会发生(尝试除以零时它会崩溃)。
想知道这个大商背后的原理。不确定这是否只是我还需要发现的其他错误。 有人可以帮我开发另一个具有相同功能的程序吗?
除以零是undefined behaviour, see C11 standard 6.5.5#5(终稿)。
获得陷阱或 SIGFPE 只是 CPU/OS 的礼貌。作为典型 RISC CPU 的 PowerPC 不会捕捉到它,因为它可以通过在进行实际除法之前对除数进行简单检查来安全地检测到。 x86 OTOH 确实 捕捉到这个 - 典型的 CISC 行为。
如果更高层标准要求,您可能错过了自动发出此检查的编译器选项。 POSIX 例如不强制执行 SIGFPE,这是可选的。
根据 PPC 体系结构手册(您可以从 IBM 获得),在 PPC 上除以 0 不会产生任何类型的信号或陷阱;相反,您只会得到一些因处理器而异的未定义值。在您的情况下,它看起来是您在将正数除以 0 时生成 MAXINT(最大正整数)的特定 PPC 变体。