Я выяснил, что операции, выполняемые сначала в выражении, выполняются справа налево, несмотря на приоритет операторов. Я создал простой класс для отладки:Почему операторы с более высоким приоритетом вызываются справа налево в C++?
class Integer
{
int i;
public:
Integer(int v = 0) : i(v)
{}
const Integer& operator++()
{
cout << "++integer\n";
i += 1;
return *this;
}
const Integer operator++(int)
{
cout << "integer++\n";
Integer temp(i);
i += 1;
return temp;
}
friend ostream& operator<<(ostream &os, const Integer &r);
friend const Integer operator+(const Integer &l, const Integer &r);
friend const Integer operator*(const Integer &l, const Integer &r);
};
ostream& operator<<(ostream &os, const Integer &r)
{
os << r.i;
return os;
}
const Integer operator+(const Integer &l, const Integer &r)
{
cout << "integer+integer " << l.i << ' ' << r.i << "\n";
return Integer(l.i + r.i);
}
const Integer operator*(const Integer &l, const Integer &r)
{
cout << "integer*integer " << l.i << ' ' << r.i << "\n";
return Integer(l.i * r.i);
}
И я использую его здесь (два примера):
Integer z, a(1), b(2), c(3), d(4);
z = a + a * b + ++d + b * c;
cout << z << endl;
Integer x = 3;
cout << x << ' ' << x++ << ' ' << ++x << ' ' << x + x << endl;
Выход:
integer*integer 2 3
++integer
integer*integer 1 2
integer+integer 1 2
integer+integer 3 5
integer+integer 8 6
14
integer+integer 3 3
++integer
integer++
5 4 5 6
Таким образом, умножение идет перед приращением (despite its lower priority), но результат, как и следовало ожидать. Второй случай более интересен - постинкрементация имеет более высокий приоритет, чем преинкрементация, и оба должны быть выполнены до оператора +, поэтому я ожидал увидеть «5 3 5 10», но, поскольку операции выполняются справа налево, постинкрементация получает 4 в качестве аргумент и добавление производится по базовому значению.
Я подозреваю, что он не имеет побочных эффектов, если операторы, которые меняют объект, не используются в выражениях, но мне интересно, есть ли какая-либо причина, по которой это выполняется?
Ваш второй вывод содержит * неопределенное поведение *. UB и ваше «открытие» - это потому, что выражения не * секвенированы *. См. [Неопределенное поведение и точки последовательности] (http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points). –
Они содержат неопределенное поведение: https://stackoverflow.com/questions/4347010/is-i-undefined-behavior – Galik
Во-первых, на поведение, которое вы видите, также влияет ассоциативность операторов (свойство, не зависящее от приоритета). Второй оператор, как и в предыдущих комментариях, имеет неопределенное поведение. – Peter