Неопределенное поведение в C

На этом веб-сайте в последнем разделе они предоставили f(i = -1, i = -1) в качестве примера. неопределенного поведения из-за непоследовательного вычисления подвыражений в аргументах функции. Но поскольку после оценки всех аргументов функции и указателя функции и перед фактическим вызовом функции есть точка следования, f всегда будет вызываться с (-1, -1), а i будет назначаться -1. Есть ли вероятность, что этого не произойдет?


person Sourav Kannantha B    schedule 10.02.2021    source источник
comment
Возможно, функция изменяет i (глобальную переменную?)   -  person pmg    schedule 10.02.2021
comment
Может быть, но все же не будет ли это определенным поведением? Поскольку в конце я буду «определенно» иметь значение, присвоенное внутри «f», а не -1.   -  person Sourav Kannantha B    schedule 10.02.2021
comment
Просто для ясности: запятая внутри вызова функции не является точкой последовательности. Порядок оценки параметров функции не указан, так что это действительно UB.   -  person Andrew Henle    schedule 10.02.2021
comment
В связанном ответе есть (слегка надуманный) пример того, что может пойти не так.   -  person dratenik    schedule 10.02.2021
comment
@dratenik Учитывая современные высококонвейерные процессоры, которые фактически действительно выполняют несколько инструкций параллельно, я бы не сказал, что этот пример каким-либо образом надуман.   -  person Andrew Henle    schedule 10.02.2021
comment
@dratenik точно ... это ответ на мой вопрос. Спасибо, и извините за дубликат :(   -  person Sourav Kannantha B    schedule 10.02.2021
comment
@SouravKannanthaB: Стандарт позволяет реализациям расширять язык, указывая, как они будут вести себя в ситуациях, выходящих за рамки тех, которые предусмотрены Стандартом, особенно в тех, где каждая реализация на сегодняшний день вела себя последовательно. На большинстве платформ было бы ничего не стоит рассматривать запись объекта со значением, которое он уже содержит, как одно действие без побочных эффектов, но стандарт позволяет компилятору, например, обрабатывать каждый аргумент, очищая i и затем уменьшая его, и чередовать операции как clear i; очистить я; уменьшить i; уменьшить i; что в данном случае...   -  person supercat    schedule 10.02.2021
comment
... нарушит поведение программы. ИМХО, качественные компиляторы стремятся придерживаться принципа, что если части Стандарта и документации реализации однозначно описывают поведение какого-то действия, а некоторые другие части характеризуют перекрывающуюся категорию действий как Undefined, то реализация должна отдавать приоритет отсутствующей первой документально подтвержденная и веская причина поступать иначе. К сожалению, некоторые свободно распространяемые компиляторы добились популярности без соблюдения таких принципов.   -  person supercat    schedule 10.02.2021


Ответы (2)


... есть точка последовательности после оценки

Конечно. После оценки, так что это бесполезно. Проблема здесь в том, что есть два непоследовательных побочных эффекта на i перед точкой последовательности. Формально это УБ.

person Lundin    schedule 10.02.2021
comment
Если бы i присваивались разные значения, то оно было бы неопределенным, поскольку значение i нельзя предвидеть... Но в этом случае я всегда оценивал бы значение -1.. Разве это не так? - person Sourav Kannantha B; 10.02.2021
comment
@SouravKannanthaB Нет, значение не имеет значения. Предположим, у нас есть какой-то экзотический сценарий, в котором i является энергозависимым аппаратным регистром, и каждая запись в него вызывает какие-то изменения в аппаратном обеспечении. Точно не определено, когда и сколько раз этот код будет записывать в этот аппаратный регистр. - person Lundin; 10.02.2021
comment
@SouravKannanthaB В более реалистичном примере, таком как основной компилятор x86 для ПК, он, вероятно, попытается сделать что-то, казалось бы, полезное из ситуации, и, скорее всего, просто передаст значение -1. Но нет никаких гарантий какого-либо конкретного поведения, просто вопрос качества реализации выходит за рамки языка C. - person Lundin; 10.02.2021

Это неопределенное поведение, потому что так говорит стандарт. Изменение переменной без точки следования между изменениями называется UB. Нет, если обе модификации не устанавливают одно и то же значение исключения из правила.

person bolov    schedule 10.02.2021
comment
Таким образом, вы имеете в виду «с этими конкретными значениями», это может привести к ожидаемому поведению, но подобное выражение с двумя разными значениями приведет к неопределенному поведению. Конечно... - person Sourav Kannantha B; 10.02.2021
comment
@SouravKannanthaB Нет, это означает: [...] нет исключений из правил. - person Ian Abbott; 10.02.2021