2010-10-21 4 views
3
#include <iostream> 
using namespace std; 

main(){ 

int i = 5; 

cout << i++ << i--<< ++i << --i << i << endl; 


} 

выше программа составлена ​​с г ++ дает выход:Поведение после приращения соиЬ

45555 

В то время как в следующей программе:

int x=20,y=35; 

x =y++ + y + x++ + y++; 

cout << x<< endl << y; 

дает результат в виде

126 

37 

Может кто-нибудь объяснить результаты.

+1

* «Поведение после приращения prinf» * Вы не используете 'printf'. Вы используете потоки ввода-вывода. –

+1

Это относится к категории тех, кто заботится. Глупый вопрос задал миллион раз, прежде чем сделать быстрый поиск, и вы увидите. Но даже если бы это было определено, вы все равно не делали бы этого в реальной жизни, чтобы снова заботиться. –

+3

@Martin: lol ... может добавить тег «who-cares»? Это было бы весело. Я подумывал о добавлении «не-снова!». тег тоже. –

ответ

2

Неопределенное поведение, так что все может случиться

4

Результат выражения второй программы является неопределенным. Компилятору даже разрешено отключить компьютер :-) Вам не разрешается изменять переменную дважды в одной точке последовательности (в данном случае: от = до ;).

Edit:

Подробные объяснения см the C FAQ, в частности question 3.2.

+0

* «Вам не разрешено изменять переменную дважды в одной точке последовательности» * Вы говорите, что 'x = y ++ + y + x ++ + y ++;' некорректен? –

+2

T.J. Кроудер> да. даже x = x ++ недопустим. – nothrow

+0

@Yossarian: Да, я только что видел 'x ++' (я думал, что он говорил о 'y ++' stuff). Удивленный это недействительно. * Бесполезно *, но меня удивляет «недействительным». (BTW: Если вы положили '@' в начале ответа на комментарий, дающий имя пользователя, он уведомит их, что у них есть комментарий. Например, '@TJ Crowder:', а не 'TJ Crowder>') –

2

Добавление к другу ответов:

Если вы используете g++, используя опцию -Wsequence-point говорит, что:

$ g++ -Wsequence-point a.cpp 
a.cpp: In function ‘int main()’: 
a.cpp:8: warning: operation on ‘i’ may be undefined 
              ^^^^^^^^^ 
+3

Еще одна причина использовать предупреждения. Еще один. –

9
cout << i++ << i-- 

семантически эквивалентно

operator<<(operator<<(cout, i++), i--); 
      <------arg1--------->, <-arg2-> 

$ 1.9/15- «Когда ca заполняя функцию (или нет функции инлайн), каждое вычисление значения и побочного эффекта, связанного с любым выражением аргумента или с выражением постфикса, обозначающое называемой функцией , секвенируют, прежде чем выполнения каждого выражения или инструкция в теле вызываемой функция. [Примечание: вычисления значений и побочные эффекты, связанные с , выражают разные аргументы . -end отметить]

C++ 0x:

Это означает, что оценка аргументов arg1/arg2 являются unsequenced (ни один из них секвенировали до другого).

В том же раздел в проекте стандарт также говорится,

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

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

operator<<(operator<<(cout, i++), i--); 
            ^the interesting sequence point is right here 

Как видно, оценка как arg1 и arg2 приводят к побочным эффектом на скалярной переменной «я ', и, как мы видели выше, побочные эффекты не имеют последствий.

Поэтому код имеет неопределенное поведение. Так что это значит?

Вот как определяется «неопределенное поведение» :) в стандарте.

Допустимое неопределенное поведение диапазоны от игнорирования ситуации полностью с непредсказуемыми результатами, чтобы Нахождения в процессе перевода или программе исполнения в документированной манере характеристики окружающей среды (с или без выдачи диагностики сообщение), до завершения перевода или исполнения (с сообщением ). Многие ошибочные программные конструкции делают не порождают неопределенное поведение; они должны быть диагностированы .

Вы видите корреляцию с @ ответ DarkDust в 'Компилятор даже позволил установить ваш компьютер в огне :-)

Таким образом, любой вывод, который вы получите от такого кода на самом деле в страшном царстве неопределенное поведение.

Не делайте этого.

Единственное, что defined примерно такой код является то, что он помогает OP и многие из нас получают много голосов (если правильно ответили) :)

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