почему f = f ++ небезопасно в c?

Я прочитал о «побочном эффекте» на этом веб-сайте:

но до сих пор не понимаю, почему f = f++ считается небезопасным?

Кто-нибудь может объяснить?


person Community    schedule 07.11.2009    source источник
comment
Повторяющаяся (хотя и не совсем очевидная, если вы не знаете, почему) stackoverflow.com/questions/1678519/difference-between-i-and-i   -  person Martin Beckett    schedule 07.11.2009
comment
Также где-то возникает вопрос, почему ++ i ++ является незаконным, но его невозможно найти!   -  person Martin Beckett    schedule 07.11.2009
comment
Этот вопрос явно спрашивает, почему эта конструкция небезопасна. Вопрос, на который вы ссылаетесь, содержит недопустимый код , потому что эта конструкция небезопасна. Два разных совершенно актуальных вопроса.   -  person joshperry    schedule 07.11.2009
comment
да, именно поэтому я не голосовал за закрытие - но стоит прочитать и другую ветку.   -  person Martin Beckett    schedule 07.11.2009


Ответы (5)


Проблема заключается в точках последовательности. В этом статусе есть две операции без точки последовательности, поэтому нет определенного порядка для оператора, выполняется ли сначала присвоение или приращение?

Ничто не говорит о том, что это небезопасно, это просто undefined, что означает, что разные реализации могут иметь разные результаты или может отформатировать ваш жесткий диск ...

person joshperry    schedule 07.11.2009
comment
Я думаю, что большинство людей сочли бы форматирование диска небезопасным последствием f = f++. Хотя я думаю, что большинство людей говорят «небезопасно», не имея в виду, что это может что-то разрушить, но что вы не можете зависеть от того, что он сделает. - person Michael Burr; 07.11.2009
comment
В стандартах C и C ++ термин «неопределенное поведение» явно используется повсюду, особенно в разделе, в котором подробно описывается порядок выполнения точки последовательности. Я просто использовал преувеличение, чтобы подчеркнуть разницу между небезопасным и неопределенным. - person joshperry; 07.11.2009
comment
На самом деле это не так, он просто указывает undefined. Подумайте о разнице между NULL и 0 (очевидно, не в C ++). Ноль - это значение, NULL - отсутствие значения. Неопределенный означает, что результатом может быть что угодно; да, включая небезопасные вещи, но не обязательно. - person joshperry; 05.12.2009

Использование x и x++ (или ++x) в одном операторе - это неопределенное поведение в C. Компилятор может делать все, что захочет: либо увеличивать x перед выполнением присваивания, либо после этого. Взяв код Олафура, он может дать f == 5 или f == 6, в зависимости от вашего компилятора.

person Arthur Reutenauer    schedule 07.11.2009

Статья по ссылке (очищено) предоставленный вами ответ. «C почти не обещает, что побочные эффекты будут возникать в предсказуемом порядке в пределах одного выражения». Это означает, что вы не знаете, в каком порядке будут появляться символы = и ++. Это зависит от компилятора.

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

person shoover    schedule 07.11.2009
comment
Еще одно уточнение - это зависит не только от компилятора. То, что может делать компилятор, может вообще не иметь смысла - даже до такой степени, что два экземпляра одного и того же оператора (с одинаковым начальным значением для f) могут дать совершенно разные результаты. - person Michael Burr; 07.11.2009

Из стандарта

6.5 (2) Если побочный эффект на скалярный объект не упорядочен относительно другого побочного эффекта на тот же скалярный объект или вычисления значения с использованием значения того же скалярного объекта, поведение не определено. Если существует несколько допустимых порядков подвыражений выражения, поведение не определено, если такой неупорядоченный побочный эффект возникает в любом из порядков. 74)

74) В этом абзаце представлены неопределенные выражения операторов, такие как

             i = ++i + 1;
             a[i++] = i;

позволяя

             i = i + 1;
             a[i] = i;
person John Bode    schedule 07.11.2009

В этом отношении я поддерживаю ответ Артура. Хотя реализация оператора пост-инкремента, то есть f ++, сбивает с толку, она не считается небезопасной. Вы должны сначала понять, как компилятор интерпретирует это. будет ли он увеличивать f после того, как встретит завершение предложения (;) или сразу после использования значения f.

person Aditya    schedule 07.11.2009
comment
Это undefined в смысле стандарта C. Это не тот случай, когда вы должны знать, что делает компилятор. Компилятор может делать что угодно, в том числе давать значение f, которое не соответствует ни одному из порядков атомарных инструкций, которые, по вашему мнению, он должен генерировать. - person Pascal Cuoq; 07.11.2009