Компиляторам разрешается предполагать, что код не вызывает неопределенного поведения, и использовать это предположение при оптимизации кода.
Для любого значения, отличного от n==0
, выражение n/n
оценивается как 1. Поскольку погружение на ноль - неопределенное поведение в C, компилятор может предположить, что этот сценарий никогда не происходит, то есть он может предположить, чтоn!=0
.Поскольку это может предполагать, что компилятор может заменить медленный n/n
дешевым постоянным значением 1
.Вероятно, именно это и происходит с рассматриваемым кодом.
Конечно, компилятору не требуется делать какие-либо подобные предположения, и он может генерировать фактическое деление.В зависимости от аппаратного обеспечения, которое выполняет код, конкретный аппаратный сигнал (или исключение) может сработать в таком случае деления на ноль.Я сомневаюсь, что любой разумный компилятор будет генерировать деление в этом примере для оптимизированного кода , потому что деление очень медленное, и согласно стандарту константа 1
достаточно хороша.Тем не менее, вполне вероятно, что в режиме отладки произойдет фактическое деление.
Подобные вещи случаются при оптимизации другого неопределенного поведения, такого как int
overflow:
void f(int x)
{
if (x > x + 1)
// executed only in case of overflow,
// which is undefined behavior,
// and hence likely optimized out.
overflow_error();
...
Don 'не полагайтесь на неопределенное поведение - оно не предсказуемо.