模数是否溢出?

Red*_*Red 7 c++ integer-overflow visual-c++ c++11

我知道(INT_MIN/-1)溢出,但(INT_MIN%-1)没有溢出.至少这是两个编译器中发生的事情,一个是前c ++ 11(VC++ 2010),另一个是后c ++ 11 GCC 4.8.1

int x = INT_MIN;
cout << x / -1 << endl; 
cout << x % -1 << endl;
Run Code Online (Sandbox Code Playgroud)

得到:

-2147483648
0
Run Code Online (Sandbox Code Playgroud)

此行为标准是定义的还是实现定义的?还有其他任何情况下除法操作会溢出吗?并且是否存在模数运算符溢出的情况?

Sha*_*our 11

根据CERT C++安全编码标准模数可以溢出它说:

[...]当被除数等于有符号整数类型的最小(负)值且除数等于-1时,在模运算期间可能发生溢出.

他们建议采用以下检查方式以防止溢出:

signed long sl1, sl2, result;

/* Initialize sl1 and sl2 */

if ( (sl2 == 0 ) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
  /* handle error condition */
}
else {
  result = sl1 % sl2;
}
Run Code Online (Sandbox Code Playgroud)

C++标准草案部分5.6 乘法运算4说(重点煤矿):

二元/运算符产生商,二元%运算符从第一个表达式除以第二个表达式得到余数.如果/或%的第二个操作数为零,则行为未定义.对于积分操作数,/运算符产生代数商,丢弃任何小数部分; 81 如果商A/B是结果的类型,(A/B)*B + A%b等于一个表示的; 否则,a/b和%b的行为都是未定义的.

CERT文档C版本提供了一些关于如何%在某些平台上工作以及在某些情况下INT_MIN % -1可能产生浮点异常的更多信息.

防止溢出的逻辑与上面的逻辑相同%.

  • @ZacHowland看起来自*N3485以来添加*否则*部分,所有的草稿都有相同的语言.这[前一个主题](http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents)有很多链接到草稿. (2认同)