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

Я сделал этот код

#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;
}

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

Ответ 1

Вы вызываете undefined поведение. Вы использовали точки последовательности, использование которых undefined в C.

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

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

предупреждение: операция на "i" может быть undefined [-Wsequence-point]

Live demo здесь.

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

Ответ 2

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

     arr[i++] = i;

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

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

Ответ 3

"Он работает так, как ожидалось" является одним из возможных результатов для поведения undefined.

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

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