2010-11-22 4 views
7

Да, я прочитал статью на sequence points. Однако я не мог понять, почему ++i = 2 будет ссылаться на неопределенное поведение? Конечное значение i было бы 2 независимо от чего-либо, так как получилось выражение ub?Еще один вопрос, связанный с точками последовательности

фрагмент кода

int main() 
{ 
    int i =0; 
    ++i=2; 
    return 0; 
} 

К сожалению мой английский не очень хорошо.

ответ

9

Это значение будет тем, что вы утверждаете, так как UB может проявляться среди других возможных сценариев. Программа может выводить то, что вы ожидаете, выводить некоторые несвязанные данные, сбой, поврежденные данные или тратить все ваши деньги на заказ пиццы. Как только стандарт C++ говорит, что некоторая конструкция UB, вы не должны ожидать какого-либо конкретного поведения. Наблюдаемые результаты могут варьироваться от одной программы к другой.

+0

но как результат может отличаться от 2? Я пытался использовать несколько онлайн-и офлайн-компиляторов, включая gcc, msvC++, intel C++. я ничего не отличался от 2. – AMS

+1

@AMS: Что делать, если программа также потратила все ваши деньги или отправила все ваши пароли третьей стороне (http://stackoverflow.com/questions/908872/whats-the-worst-example- из-неопределенными-поведение-на самом деле, возможно/3554343 # 3554343)? – sharptooth

+0

И это совсем не шутка - я призываю вас фактически перейти по ссылке и прочитать ответ за ней. – sharptooth

0

С точно такой же ссылке вы предоставляете:

  • Кроме того, предшествующее значение должно быть доступны только для определения значения для хранения.

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

Здесь на левой стороне оператора =, доступ к i не участвует в вычислении значения написанного.

0

++ i (должно быть) rvalue и, следовательно, не может использоваться как lvalue, но (++ i) = 2; должен работать нормально. Я не считаю, что это UB, но, как всегда, я могу ошибаться.

+0

Да, вы ошибаетесь. Добавление скобок не изменяет синтаксический разбор этого выражения, префикс operator ++ возвращает lvalue. UB является результатом записи в одно и то же значение дважды в одной и той же точке последовательности. –

+0

@Greg Rogers: Спасибо! –

11

Это выглядит очевидным для вас, потому что, очевидно, i будет первый быть назначен i+1, то второй присваивается значение 2.

Однако оба этих заданий происходит в течение одной и той же точки последовательности, поэтому она до компилятора, который происходит Фрист и что случается второй, поэтому различные реализации компилятора могут генерировать код, который будет давать разные результаты, поэтому это UB ,

+4

Yeap, а также компилятор не требуется для создания одной и той же программы в разных компиляторах. Печать 0 на ane компиляции, стирает диск на другом. – sharptooth

1

Вызов ++i = 2; сам по себе не вызывает неопределенного поведения; любой компилятор может, если захочет, выполнить очень определенное действие при достижении этого кода. Однако в стандарте C++ указано, что такая операция не определена, поэтому компилятор может сделать что-то неожиданное (например, удалить все файлы на диске C или отправить текстовое сообщение папе) и по-прежнему быть совместимым компилятором. Единственное, что делает этот UB, это то, что стандарт говорит, что это UB.

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

2

Неопределенное поведение происходит потому, что компилятор может реализовать следующий код:

++i = 2; 

либо как:

i = 2; 
++i; 

или

++i; 
i = 2; 

Это не определено в языке, компилятор мог бы выбрать любой из вышеперечисленных. Первый будет производить 3 и второй 2. Так что это неопределенно.

Смежные вопросы