Хорошо ли определена программа перед строкой, вызывающей неопределенное поведение?

Рассмотрим этот код:

int main()
{
    printf("Hello World!\n");
    int i;
    i = i++ + ++i; // UB
}

Гарантированно ли этот код напечатает «Hello World!»? Последняя строка вызывает неопределенное поведение, но делает ли это недействительной всю программу?

I found this but that question is about C++. This is about C.

It's not a dup of Undefined behavior and sequence points since it's C++. The answer may or may not be the same, but this question is about C.

Мне кажется, я где-то читал, что программа со строкой, вызывающей неопределенное поведение, на самом деле является программой с неопределенным поведением. В зависимости от оптимизации компилятора перед указанной строкой могут происходить странные вещи.

kabanus 10.09.2018 11:23

@kabanus: Речь идет о стандарте, как кажется. Оптимизация компилятора выходит за рамки стандарта. Настолько актуальна абстрактная машина, которая в лучшем случае предоставляет точки последовательности. Однако, если не считать таких искусственных программ, для производственного кода этот вопрос не имеет особого смысла.

too honest for this site 10.09.2018 15:15

@toohonestforthissite Я имел в виду, что компилятор делает все, что ему нравится, но я понимаю вашу точку зрения.

kabanus 10.09.2018 18:00

@melpomene Я добавил Конкретный ответ C, который также охватывает C++, так что теперь это точная копия.

Shafik Yaghmour 10.09.2018 21:09
4
4
135
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из стандарта C (3.4.3):

undefined behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

С последующим :

NOTE Possible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).

Это означает, что стандарт не налагает никаких гарантий на поведение всей программы, включая «более ранние» операции.

Однако конкретные реализации могут добавлять определенные гарантии для определенных экземпляров неопределенного поведения (например, обратитесь к документации вашего компилятора). И на практике, многие реализации по большей части ведут себя так, как вы описываете. Однако оптимизации, как правило, затрудняют это гарантировать. Кроме того, компиляторы иногда удаляют целые ветки, если они содержат неопределенное поведение.

Вот несколько практических примеров того, как это действительно происходит: blog.regehr.org/archives/232

melpomene 10.09.2018 11:52

@melpomene: качественная реализация, подходящая для низкоуровневого программирования на конкретной целевой платформе, должна допускать возможность нестабильного доступа, запускающего любое действие, которое такой доступ может произвести на этой платформе. Если реализация никогда не будет использоваться для низкоуровневого программирования на платформе, которая определяет поведение конкретного изменчивого доступа, например, запуск сигнала, а затем оптимизация неконтролируемого разделения через энергозависимый доступ. Такое предположение кажется изворотливым для реализаций, которые заявляют, что подходят для использования с произвольными платформами.

supercat 10.09.2018 22:13

Другие вопросы по теме