Согласно стандарту C ++ (5/5) деление на ноль является неопределенным поведением. Теперь рассмотрим этот код (существует множество бесполезных операторов, которые мешают компилятору оптимизировать код):
int main()
{
char buffer[1] = {};
int len = strlen( buffer );
if( len / 0 ) {
rand();
}
}
Visual C ++ компилирует if
-это утверждение так:
sub eax,edx
cdq
xor ecx,ecx
idiv eax,ecx
test eax,eax
je wmain+2Ah (40102Ah)
call rand
Ясно, что компилятор видит, что код должен делиться на ноль - он использует шаблон xor x,x
для обнуления ecx
, который затем служит вторым операндом в целочисленном делении. Этот код определенно вызовет ошибку «деление на целое число ноль» во время выполнения.
IMO такие случаи (когда компилятор знает, что код всегда будет делиться на ноль) стоят ошибки времени компиляции - Стандарт не запрещает это. Это помогло бы диагностировать такие случаи во время компиляции, а не во время выполнения.
Однако я разговаривал с несколькими другими разработчиками, и они, похоже, не согласны - их возражение заключается в том, «что если автор хочет разделить на ноль до ... ммм ... тестовой обработки ошибок?"
Намеренно делить на ноль без понимания компилятора не так сложно - используя __declspec(noinline)
Декоратор функций, специфичный для Visual C ++:
__declspec(noinline)
void divide( int what, int byWhat )
{
if( what/byWhat ) {
rand();
}
}
void divideByZero()
{
divide( 0, 0 );
}
, который гораздо более читабелен и удобен в обслуживании. Эту функцию можно использовать, когда ему «нужно проверить обработку ошибок», и во всех остальных случаях получится приятная ошибка во время компиляции.
Я что-то упустил? Нужно ли разрешать выдачу кода, который, как знает компилятор, делит на ноль?