Это неопределенное поведение, когда выполнение программы зависит от порядка выполнения?

В выражении вида

f( g(), h() );

порядок оценки g() и h() не определен. Уточняется только, что одно должно произойти раньше другого. Если g() и h() имеют видимые побочные эффекты, от которых зависит выполнение программы, является ли это неопределённым поведением?


person Ralph Tandetzky    schedule 02.01.2016    source источник
comment
stackoverflow.com/a/621548/276949 - он будет определен для конкретного компилятора, но не переносим.   -  person Martin Konecny    schedule 02.01.2016
comment
Не неопределенное поведение заранее ... но оценка может быть такой в ​​одной оценке, а в следующий раз - в другом порядке. Если есть UB для определенного заказа, то программа в целом имеет UB, независимо от того, есть ли когда-либо в вашей реализации этот конкретный заказ.   -  person Johannes Schaub - litb    schedule 02.01.2016
comment
Это не UB, но как бы вы это ни называли - ваша программа в любом случае сломана!   -  person Oliver Charlesworth    schedule 02.01.2016
comment
Пример: int x = 1; int f() { return 1 / x; } int g(int,int) { return --x; } int main() { g(g(0, 0), f()); }. Эта программа имеет неопределенное поведение, хотя ваша конкретная реализация может никогда не вычислять g(0,0) до f().   -  person Johannes Schaub - litb    schedule 02.01.2016


Ответы (2)


«Неопределенное поведение» имеет очень конкретное техническое значение: это означает, что нет никаких ограничений на то, что может делать программа. Это может поджечь компьютер или оскорбить пользователя. Здесь порядок выполнения не указан — есть несколько вариантов того, что может произойти, в зависимости от порядка, в котором оцениваются вещи. Вы просто не можете точно предсказать, какой из них будет, не зная больше о компиляторе, оптимизаторе и среде выполнения.

person templatetypedef    schedule 02.01.2016
comment
... Но пока ни один из этих заказов не приводит к UB, все в порядке. - person Deduplicator; 02.01.2016
comment
@Deduplicator Да, определенно. Люди постоянно пишут код, подобный приведенному выше, и до тех пор, пока функции не выполняют Жестокие и Необычные действия с глобальным состоянием, проблем не возникает. - person templatetypedef; 02.01.2016
comment
@Deduplicator - Но не в том случае, если обе функции имеют видимые побочные эффекты, от которых зависит выполнение программы, - тогда ваша программа будет случайным образом прерываться, независимо от UB. - person Oliver Charlesworth; 02.01.2016
comment
@OliverCharlesworth Нет, если побочные эффекты обеих функций могут иметь место без другого. Если g() записывает в файл g, h() записывает в файл h, а f(g(), h()) читает файлы g и h, не имеет значения, в какой файл была записана первая, но имеет значение, что побочные эффекты обеих функций проявляются до запуска f . - person ; 02.01.2016
comment
В книге «Язык программирования C++» Страуструп пишет на странице 260: «Зависимость от порядка выражений аргументов — это очень плохой стиль и неопределенное поведение. - так он ошибается? - person marcinj; 02.01.2016
comment
@hvd - В сочетании с заголовком вопроса (выполнение программы зависит от порядка выполнения) я готов поспорить, что ОП думает о более пагубных примерах, где важен порядок побочных эффектов. - person Oliver Charlesworth; 02.01.2016
comment
@OliverCharlesworth Если ваша интерпретация вопроса верна, то да, я с вами согласен. Я не так читаю вопрос, но я определенно понимаю, почему вы его так читаете. - person ; 02.01.2016
comment
@luksan: Книга Страуструпа была написана до того, как термины «неопределенное поведение» и «неопределенное поведение» имели четко определенные (в смысле спецификации) и разные значения... - person Chris Dodd; 02.01.2016
comment
@luskan Я бы подумал, что зависимость от чего-то означает, что если это не держится, все сильно ломается (другими словами, неопределенное поведение). ОП касается лишь того, могут ли измениться видимые побочные эффекты. Если вас не волнует их порядок, то вы не зависите от них (ИМО). - person Johannes Schaub - litb; 02.01.2016

Нет, это не так. Термин неопределенное поведение означает, что в программе может произойти все (включая сбои). Здесь поведение непредсказуемо, что означает, что может произойти одно или другое, и вы не можете полагаться на порядок оценки.

Большая разница в том, что в вашем случае теоретически вы могли бы вернуться в свою программу, проверив, какой порядок был выбран после каждого вызова, и действуя соответственно. С другой стороны, как только вы столкнулись со случаем неопределенного поведения, вы облажались: он может укусить вас в любое время, в любом месте, любым способом, пока программа не завершится.

person Ilya    schedule 02.01.2016