#include <iostream>
int a(int &x) {
x = -1;
return x;
}
int main () {
int x = 5;
std::cout << a(x) << " " << x << std::endl;
}
Почему вывод «-1 5»?
PS: компилятор это:
i686-apple-darwin11-llvm-g ++ — 4.2 (GCC) 4.2.1 (на основе Apple Inc., сборка 5658) (сборка LLVM 2336.11.00)
PS: скомпилировано без какой-либо оптимизации.
В этой строке:
std::cout << a(x) << " " << x << std::endl;
порядок оценки a(x)
а также x
не указано Это неопределенное поведение, что происходит, в вашем случае компилятор решил оценить x
первый, a(x)
после этого.
Порядок, в котором a(x)
а также x
оцениваются неопределенные [1]. Чтобы убедиться, что x
не будет изменено в пределах одного и того же выражения (и при этом можно избежать неопределенного поведения), вы можете сделать:
int x = 5;
int y = a(x);
std::cout << y << " " << x << std::endl;
Порядок оценки не определен и, следовательно, неуточненное поведение или a(x)
или же x
можно оценить в первую очередь. С уважением к Проект стандарта C ++ раздел 1.9
Выполнение программы параграф 15 говорит (акцент мой):
[…]Если не указано иное, вычисления операндов отдельных операторов и подвыражений отдельных выражений не являются последовательными. [Примечание: В выражении, которое оценивается более одного раза во время выполнения программы, непоследовательные и неопределенно последовательные оценки ее подвыражений не должны выполняться последовательно в различных оценках. — конец примечания] […]
и это может даже отличаться между различными оценками и далее, если мы вернемся к пункту 13 это говорит:
[…]Если A не секвенируется до B, а B не секвенируется до A, то A и B не секвенируются. [Примечание: выполнение неупорядоченных оценок может частично совпадать. —Конец примечания] Оценки А и В имеют неопределенную последовательность когда A секвенируется перед B или B секвенируется перед A, но это не указано, какой.[…]
что объясняет, что это неопределенное поведение.