Проанализируйте следующий фрагмент на C и объясните, какие операции приводят к неопределённому поведению, почему компилятор может выдать неожиданный результат и как переписать код, чтобы он был корректен по стандарту C:
int i = 0

5 Ноя в 13:54
6 +6
0
Ответы
1
Фрагмент
int i = 000;
сам по себе корректен и не содержит неопределённого поведения — это обычная определённая инициализация.
Часто под таким вопросом понимают выражения, где одна и та же переменная и модифицируется, и читается в одном выражении без упорядочения (sequence point / sequencing) — это и вызывает UB. Примеры плохих выражений (они неопределённы по стандарту C):
- i=i+++1;i = i++ + 1;i=i+++1;
- i=++i;i = ++i;i=++i;
- i=i+++i++;i = i++ + i++;i=i+++i++;
- a[i++]=i;a[i++] = i;a[i++]=i;
Почему это UB: стандарт C запрещает модификацию объекта более одного раза или модификацию и одновременное чтение его значения в одном «неупорядоченном» фрагменте выражения. В таких выражениях порядок вычислений и применения побочных эффектов не определён (в C11/C17 говорят об unsequenced/indeterminately sequenced), поэтому поведение — неопределённое.
Последствия для компилятора: при наличии UB компилятор может предположить, что такие ситуации не встречаются, и выполнить оптимизации или перестановки кода, которые приведут к неожиданному результату (удаление операций, изменение порядка, выдача «странных» значений). Нельзя полагаться на то, что результат будет «интуитивным» на конкретном компиляторе.
Как переписать корректно (варианты):
- Для i=i+++1;i = i++ + 1;i=i+++1; — явно сохранить старое значение:
int tmp = i;
i = tmp + 111;
или если цель просто увеличить:
i += 111;
или
i++;
- Для i=++i;i = ++i;i=++i; — просто:
++i;
(или, если нужна присвоенная величина, использовать tmp)
- Для i=i+++i++;i = i++ + i++;i=i+++i++; — использовать временные:
int t1 = i++;
int t2 = i++;
i = t1 + t2;
- Для a[i++]=i;a[i++] = i;a[i++]=i; — сохранить индекс отдельно:
int idx = i++;
a[idx] = i;
или
a[i] = i;
i++;
Общее правило: не изменяйте и не читайте одно и то же скалярное значение в одном выражении без явного упорядочения (разнесите на несколько операторов или используйте временные переменные). Это гарантирует поведение, согласованное со стандартом C.
5 Ноя в 14:22
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир