是否除以零伴随着C ++中有用的运行时错误? [英] Is dividing by zero accompanied with a runtime error ever useful in C++?

查看:176
本文介绍了是否除以零伴随着C ++中有用的运行时错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据C ++标准(5/5)除以零是未定义的行为。现在考虑这个代码(许多无用的语句有防止编译器优化代码):

According to C++ Standard (5/5) dividing by zero is undefined behavior. Now consider this code (lots of useless statements are there to prevent the compiler from optimizing code out):

int main()
{
    char buffer[1] = {};
    int len = strlen( buffer );
    if( len / 0 ) {
        rand();
    }
}

Visual C ++编译 if - 如下所示的状态:

Visual C++ compiles the if-statement like this:

sub         eax,edx 
cdq 
xor         ecx,ecx 
idiv        eax,ecx 
test        eax,eax 
je          wmain+2Ah (40102Ah) 
call        rand

显然,编译器看到代码是除以零 - 它使用 xor x,x out ecx ,然后在整数除法中提供第二个操作数。这种代码肯定会在运行时触发一个整数除零错误。

Clearly the compiler sees that the code is to divide by zero - it uses xor x,x pattern to zero out ecx which then serves the second operand in integer division. This code will definitely trigger an "integer division by zero" error at runtime.

IMO这种情况下(当编译器知道代码将始终除以零)是值得编译时错误 - 标准没有禁止。这将有助于在编译时而不是在运行时诊断这种情况。

IMO such cases (when the compiler knows that the code will divide by zero at all times) are worth a compile-time error - the Standard doesn't prohibit that. That would help diagnose such cases at compile time instead of at runtime.

然而,我跟其他几个开发人员说,他们似乎不同意 - 他们的反对是想要除以零到... emm ...测试错误处理?

However I talked to several other developers and they seem to disagree - their objection is "what if the author wanted to divide by zero to... emm... test error handling?"

有意识地除以零没有编译器意识不是那么难 - 使用 __ declspec(noinline) Visual C ++特定函数装饰器:

Intentionally dividing by zero without compiler awareness is not that hard - using __declspec(noinline) Visual C++ specific function decorator:

__declspec(noinline)
void divide( int what, int byWhat )
{
    if( what/byWhat ) {
       rand();
    }
}

void divideByZero()
{
    divide( 0, 0 );
}

当他需要测试错误处理并且在所有其他情况下有一个很好的编译时错误时,可以使用该函数。

which is much more readable and maintainable. One can use that function when he "needs to test error handling" and have a nice compile-time error in all other cases.

我错过了什么?是否需要允许发出编译器知道的除以零的代码?

Am I missing something? Is it necessary to allow emission of code that the compiler knows divides by zero?

推荐答案

除以0是未定义的行为,触发器,在某些平台上,硬件异常。我们都希望有一个更好的硬件,但是因为没有人看到适合整数与-INF / + INF和NaN值,这是相当无意义。

Dividing by 0 is undefined behavior because it might trigger, on certain platforms, a hardware exception. We could all wish for a better behaved hardware, but since nobody ever saw fit to have integers with -INF/+INF and NaN values, it's quite pointeless.

现在, 因为是未定义的行为,有趣的事情可能会发生。我鼓励你阅读Chris Lattner关于未定义的行为和优化的文章,我将在这里给出一个简单的例子:

Now, because it's undefined behavior, interesting things may happen. I encourage you to read Chris Lattner's articles on undefined behavior and optimizations, I'll just give a quick example here:

int foo(char* buf, int i) {
  if (5 / i == 3) {
    return 1;
  }

  if (buf != buf + i) {
    return 2;
  }

  return 0;
}

因为 i 用作除数,那么它不是0.因此,第二个 if 是微不足道的真实,可以被优化掉。

Because i is used as a divisor, then it is not 0. Therefore, the second if is trivially true and can be optimized away.

面对这样的转变,任何人希望一个分裂的正常行为0 ...将是非常失望。

In the face of such transformations, anyone hoping for a sane behavior of a division by 0... will be harshly disappointed.

这篇关于是否除以零伴随着C ++中有用的运行时错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆