в то время как бесконечный цикл?

Я наткнулся на этот вопрос на этом форуме

#include <iostream>

using namespace std;

int main(int argc, char** argv) {

    int x=0;
    while (x<3) {
        x = x++;
        cout << x << endl;
    }

    return 0;
}

учитывая приведенный выше код, почему цикл while бесконечен? При использовании gcc 4.4 под mac os цикл while завершается :), поэтому вопрос актуален не для всех архитектур. Вывод, который я получаю трудно, это
1
2
3

Я не вижу 0, и я предполагаю, что причина связана с двойным присвоением?


person Bob    schedule 16.03.2011    source источник
comment
Неопределенное поведение не определено   -  person Erik    schedule 17.03.2011
comment
на какой платформе он бесконечен? или я должен сказать компилятор.   -  person Piotr Salaciak    schedule 17.03.2011
comment
@Piotr: Тот, кого он упоминает в вопросе.   -  person Erik    schedule 17.03.2011
comment
под mac osx x64 (gcc 4.4) цикл завершается. По-видимому, при использовании некоторых других компиляторов и/или платформ это может быть бесконечно programmers.stackexchange.com/questions/25836/   -  person Bob    schedule 17.03.2011


Ответы (2)


x = x++;

это неопределенное поведение

person BlackBear    schedule 16.03.2011
comment
Что означает, что петля не бесконечна и не конечна? - person John; 17.03.2011
comment
@John: это означает, что мы не можем сказать, почему программа ведет себя так или иначе - person BlackBear; 17.03.2011
comment
@John: Это означает, что программа недействительна, и может произойти что угодно. - person Bo Persson; 17.03.2011
comment
Спасибо за разъяснения, ребята. - person John; 17.03.2011
comment
И обратите внимание, что на самом деле это означает что угодно. Может случиться так, что x окажется со старым значением, или новым значением, или каким-то совершенно другим значением, или программа может дать сбой, или программа может запуститься nethack или демоны могут вылетает из твоего носа. - person Anomie; 17.03.2011
comment
это не неопределенно, равно x=x; х=х+1; - person mjsr; 17.03.2011
comment
@voodoomsr: нет, компилятор может интерпретировать это. например, мне кажется, что x = x = x + 1 - person BlackBear; 17.03.2011
comment
@voodoomsr: Нет: stackoverflow.com/questions/98340/ - person John; 17.03.2011
comment
@voodoomsr: технически оператор ++ для целого числа увеличивает переменную, но результатом операции является исходное значение (см. раздел 5.2.6 [expr.post.incr]), что позволяет использовать его в выражении. Назначение происходит после этого. Так что это больше похоже на int old = x;x=x+1;x = old;. (так что здесь у нас есть бесконечный цикл). Но здесь нет точек последовательности, так что компилятор может изменить порядок операторов. int old = x;x=old;x=x+1; или x=x+1;int old=x;x=old; - person Martin York; 17.03.2011
comment
@Martin, теория говорит о другом: cplusplus.com/doc/tutorial/operators, у вас есть какая-нибудь ссылка, которая объясняет это странное поведение (книга, сайт документации, а не сайт QA)? это какое-то эмпирическое недокументированное знание? - person mjsr; 17.03.2011
comment
@voodoomsr: я процитировал вам ссылку в стандарте C++, которая точно объясняет, как работает ++. Теперь с cplusplus.com все в порядке, но это НЕ конический справочный сайт. Неопределенное поведение означает, что оптимизатор может вертеться так, как ему заблагорассудится. Моя интерпретация — это всего лишь три из многих способов, которыми оптимизатор может что-то изменить. Ваша интерпретация так же верна, когда речь идет об УБ. См. это ответить на что-то подобное - person Martin York; 17.03.2011
comment
@Martin меняет ссылку на лучшую - › Язык программирования C++, 3-е издание, написанное Страуструпом, в главе 6.2.5 говорится, что значение x++, однако, является старым значением x. Например, y= x++ эквивалентно y=(t=x, x+=1, t), где t — переменная того же типа, что и x. Теперь я понимаю, почему цикл. Оптимизаторы, которые не нарушают этот порядок операций, сохраняют x равным нулю. те, которые нарушают этот порядок, увеличивают x. Было весело, поищите происхождение этого, :) - person mjsr; 17.03.2011
comment
@voodoomsr: Опять же, язык программирования C ++, 3-е издание, хорош, но не является стандартом. Вам нужно получить копию стандарта. - person Martin York; 17.03.2011

вы никогда не увидите ноль, потому что приращение идет до cout.

person mjsr    schedule 16.03.2011
comment
Это неопределенное поведение, поскольку значение x устанавливается дважды между точками последовательности. Компилятор может выполнять присваивание и приращение в любом порядке или делать что-то еще, что может иметь для него смысл. - person Anomie; 17.03.2011
comment
я думаю по-другому, но я буду читать дальше в руководстве по С++, которое у меня есть. Давным-давно я узнал, что POSTIncrement выглядит так: x=a++; означает х=а; а=а+1; я не понимаю, почему в этой ситуации, когда a = x отличается - person mjsr; 17.03.2011