2016-05-24 3 views
0

я сделал этот кодточка последовательности в индексе массива

#include <stdio.h> 

int main(void) 
{ 
    int i = 0; 
    int arr[20]; 
    while(i < 20) 
    { 
     arr[i++] = i; 
     printf("%d\n", arr[i-1]); 
    } 
    return 0; 
} 

, который, кажется, чтобы напечатать ожидаемые результаты, почему говорят, что вы можете иметь неопределенное поведение?

+1

Вы Неопределенное поведение - так что вы * возможно * получить значение, которое вы хотите, или вы * не может * Только потому, что вы * получить *. ожидаемые значения не означают, что код правильный и четко определенный. –

+0

Как я могу проверить неопределенное поведение – Kevin

+0

Запустить указанный выше код на другом компиляторе. –

ответ

2

Вы вызываете undefined behavior. Вы использовали sequence points, использование которых не определено в С.

Вы говорите, что кажется печатать ожидаемые результаты - это может или не может, потому что это не определено. Таким образом, тот факт, что вы получаете ожидаемые значения, - это просто удача.

Что касается получения некоторых предупреждений, пожалуйста, скомпилируйте и запустите код; это действительно даст вам предупреждение:

предупреждение: операция на 'я' может быть не определено [-Wsequence точки]

Live Demo here.

Кроме того, если вы думаете, почему это просто предупреждение и не ошибка, то обратите внимание, что компилятор никоим образом не связан с сообщать обо всех ваших неопределенных поведения - его работа скомпилировать ваш код, чтобы не указывать ваше неопределенное поведение.

+1

Чтобы быть смехотворным, все «неопределенное поведение» означает, что компилятор не * требуется * для обработки ошибочного кода каким-либо особым образом; он * может * выдать диагностический и остановить перевод (ошибку), он * может * выдать диагностический и полный перевод (предупреждение), он * может * завершить перевод без диагностики. Если он завершает перевод, сгенерированный машинный код * может * завершаться с ошибкой во время выполнения, он * может * запускаться до завершения без видимых проблем, он * может * запускать Rogue. Что касается стандарта, * все * этих результатов одинаково «правильны». –

+0

@JohnBode, я полностью согласен. –

1

В зависимости от порядка оценки, первое время исполнения

 arr[i++] = i; 

может в конечном итоге установка arr[1] к 1 (если LHS сначала вычисляется) или 0 (если РИТ сначала вычисляется). Если они выполняются параллельно, результатом может быть что угодно.

Мы не можем гарантировать состояние программы после этой строки. Не используйте его.

+1

Или любой другой результат –

1

«Работает так, как ожидалось» является одним из возможных результатов для неопределенного поведения.

arr[i++] = i;явно вызван как пример неопределенного поведения в стандарте языка. Порядок, в котором оценивается каждое подвыражение, не определен; это не гарантируется слева направо. Для i == 1, любой из следующих результатов возможны:

arr[1] = 1; 
arr[1] = 2; 
arr[2] = 2; 
arr[2] = 1; 
+1

Или любой другой результат –