根据 C++ 标准 (5/5) 除以零是未定义的行为。现在考虑这段代码(有很多无用的语句来防止编译器优化代码):
int main()
{
char buffer[1] = {};
int len = strlen( buffer );
if( len / 0 ) {
rand();
}
}
Visual C++if
像这样编译 -statement:
sub eax,edx
cdq
xor ecx,ecx
idiv eax,ecx
test eax,eax
je wmain+2Ah (40102Ah)
call rand
很明显,编译器看到代码要除以零——它使用xor x,x
模式将其清零ecx
,然后在整数除法中为第二个操作数提供服务。此代码肯定会在运行时触发“整数除以零”错误。
IMO 这种情况(当编译器知道代码将始终除以零时)值得编译时错误 - 标准并不禁止这种情况。这将有助于在编译时而不是在运行时诊断此类情况。
然而,我与其他几位开发人员交谈,他们似乎不同意——他们的反对意见是“如果作者想除以零来... emm... 测试错误处理怎么办?”
在没有编译器意识的情况下故意除以零并不难 - 使用__declspec(noinline)
Visual C++ 特定的函数装饰器:
__declspec(noinline)
void divide( int what, int byWhat )
{
if( what/byWhat ) {
rand();
}
}
void divideByZero()
{
divide( 0, 0 );
}
这更具可读性和可维护性。当他“需要测试错误处理”并且在所有其他情况下都有很好的编译时错误时,可以使用该功能。
我错过了什么吗?是否有必要允许编译器知道除以零的代码的发射?