R..*_*R.. 24 c gcc overflow division modulo
gcc SIGFPE为以下代码生成浮动代码:
#include <limits.h>
int x = -1;
int main()
{
return INT_MIN % x;
}
Run Code Online (Sandbox Code Playgroud)
但是,我在标准中找不到此代码调用未定义或实现定义的行为的语句.据我所知,它需要返回0.这是gcc中的错误还是我错过了标准的一些特殊例外?
orl*_*rlp 16
查看gcc生成的汇编代码(x在程序集的前面定义为-1):
movl x, %ecx
movl $-2147483648, %eax
movl %eax, %edx
sarl $31, %edx
idivl %ecx
Run Code Online (Sandbox Code Playgroud)
第一个计算指令sarl右移-214748364831位.这导致-1投入%edx.
接下来idivl执行.这是签名操作.让我引用描述:
将组合的%edx:%eax寄存器中包含的双字的内容除以指定的寄存器或存储单元中的值.
所以,-1:-2147483648 / -1是出现这种情况的划分.-1:-2147483648解释为双字等于-2147483648(在二进制补码机器上).现在-2147483648 / -1发生了回归2147483648.繁荣!那就是一个INT_MAX.
关于为什么问题,这是gcc中的一个错误还是我错过了标准所做的一些特殊例外?
在C99标准中,这是隐式UB(§6.5.5/ 6):
... /运算符的结果是代数商,丢弃任何小数部分.88)如果商a/b是可表示的,则表达式(a/b)*b + a%b应等于a.
INT_MIN / -1 无法表示,因此这是UB.
在C89中,%运算符是实现定义的,是否是编译器错误可以辩论.该问题列在gcc上:http://gcc.gnu.org/bugzilla/show_bug.cgi? id = 30484
| 归档时间: |
|
| 查看次数: |
1499 次 |
| 最近记录: |