Странно, но если переопределить префиксную и постфиксную операцию ++, то порядок её выполнения отличается от операции со встроеным типом int.
А именно представим следующий код:
class A
{
public:
A()
:i_(0)
{
}
A(int val)
:i_(val)
{
}
const A operator ++ (int)
{
A oldVal = *this;
++i_;
return oldVal;
}
operator int() const
{
return i_;
}
A operator + (const A &rhs) const
{
A retVal;
retVal.i_ = rhs.i_ + i_;
return retVal;
}
private:
int i_;
};
int _tmain(int argc, _TCHAR* argv[])
{
A a(0);
int k = a++ + a++;
int i = 0;
int l = i++ + i++;
return 0;
}
в случае с использованием класса A, значение k равно 1, а в случае со встоеным типом int — значение l равно 0.
Так какой же все таки порядок выполнения операций + и посфиксного ++
Re: Глюк или нет. Что раньше lvalue++ или expr + expr
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Leha410, Вы писали:
B>Все встанет на свои места, если воспользоваться поиском по фразам "неопределенное поведение" и "точка следования".
а причем тут непределенное поведение?
можно записать следующим образом
...
A a(0);
int k = (a++) + (a++);
int i = 0;
int l = (i++) + (i++);
...
и будет тоже самое
Re[3]: Глюк или нет. Что раньше lvalue++ или expr + expr
Здравствуйте, Leha410, Вы писали:
B>>Все встанет на свои места, если воспользоваться поиском по фразам "неопределенное поведение" и "точка следования".
L>а причем тут непределенное поведение?
Тут имеет место быть множественная модификация объекта между двумя точками следования.
L>можно записать следующим образом L>... L> A a(0); L> int k = (a++) + (a++); L> int i = 0; L> int l = (i++) + (i++); L>... L>и будет тоже самое
Эта тема обсуждалась уже не раз и не два — воспользуйся поиском, если на самом деле интересно.
Начать можно здесь
Здравствуйте, Bell, Вы писали:
B>Тут имеет место быть множественная модификация объекта между двумя точками следования.
Ну естественно она "имеет место быть".
На самом деле вы невнимательно читаете вопрос.
А он состоит в следующем:
почему оператор постинкремента (lvalue ++) для всроенного типа выплняется после бинарного оператора сложения (expr + expr) в выражении (i++) + (i++)), а перегруженый оператор ( const A operator ++ (int) ) — перед оператором сложения. Вот и все.
Re[5]: Глюк или нет. Что раньше lvalue++ или expr + expr
Здравствуйте, Leha410, Вы писали:
L>Здравствуйте, Bell, Вы писали:
B>>Тут имеет место быть множественная модификация объекта между двумя точками следования.
L>Ну естественно она "имеет место быть".
...
А отсюда следует неопределенное поведение. Поэтому дальнейшие рассуждения на тему что до, а что после, лишены смысла.
Любите книгу — источник знаний (с) М.Горький
Re[6]: Глюк или нет. Что раньше lvalue++ или expr + expr
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Leha410, Вы писали:
L>>Здравствуйте, Bell, Вы писали:
B>>>Тут имеет место быть множественная модификация объекта между двумя точками следования.
L>>Ну естественно она "имеет место быть". B>... B>А отсюда следует неопределенное поведение. Поэтому дальнейшие рассуждения на тему что до, а что после, лишены смысла.
Спасибо разобрался. Дело в том что стандарт не определяет зависимость приоритета операций от порядка их выполнения.