Порядок оценки аргумента между цепными вызовами статической функции
Мне любопытно, почему существует разница в порядке оценки аргумента между цепными статическими функциями и функциями-членами. Из ответов на этот вопрос я вижу, что неуказано, что порядок оценки аргумента находится между такими цепными вызовами функций. Возьмем, к примеру, следующий фрагмент:
#include <iostream>
class test {
public:
static test& chain_s(test& t, int i) {
std::cout << i << " ";
return t;
}
test& chain(test& t, int i) {
std::cout << i << " ";
return *this;
}
};
int main(int, char**) {
int x = 2;
test t;
t.chain(t,++x).chain(t,++x).chain(t,++x);
x = 2; std::cout << std::endl;
t.chain_s(t,++x).chain_s(t,++x).chain_s(t,++x);
return 0;
}
В случае GCC 4.6.2 и CL 15.00.30729.01 (MSVC 9) результирующий вывод для меня
5 5 5
3 4 5
Однако мне было интересно, есть ли какая-либо причина в спецификации или если известно, почему статическая функция оценивается слева направо (с их аргументами), а для нестатической функции сначала все аргументы (справа налево от того, что я видел в других тестах).
Причина, по которой я спрашиваю об этом, - это то, что я впервые заметил это различие в поведении при попытке получить аналогичное поведение на C (с использованием структуры и указателя функции) и не удалось. Я сильно подозреваю, что это некоторая оптимизация, реализованная как в GCC, так и в MSVC для функций-членов, но я надеюсь, что кто-то здесь может пролить немного больше света на это.
Edit:
Я забыл упомянуть один важный бит информации, который поражает меня как нечетное: GCC будет предупреждать только о неуказанном поведении о цепной нестатической функции, но не о статических функциях:
a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]
GCC не обязан предоставлять такие предупреждения, чтобы он мог пропустить второе выражение, но это то, что заставляет меня поверить в то, что происходит что-то интересное.
Ответы
Ответ 1
Нет причин. Как вы говорите, порядок не указан языком.
Одной из причин использования права на левый порядок является то, что функции с переменным числом параметров, например printf
, всегда будут иметь первый параметр сверху. В противном случае это не имеет значения.
Ответ 2
В вашем коде есть поведение undefined, но, полагаю, вы это знаете. Также,
вы можете легко увидеть разницу в зависимости от флагов оптимизации. Но
в этом случае одна из вероятных причин состоит в том, что нестатические функции требуют
три аргумента, включая результаты предыдущего вызова, где as
для статических функций требуется только два, а результаты предыдущего
вызов игнорируются.