§ 1.9.13
секвенированы перед тем является асимметричным, транзитивным, попарно соотношение между оценками, выполненных одной нитью (1.10), которое индуцирует частичный порядок среди этих оценок. При любых двух оценках A и B, если A секвенирован до B, то выполнение A должно предшествовать исполнению B. Если A не секвенировано до B и B не секвенированы до A, тогда A и B не подвержены , [Примечание. Выполнение необоснованных оценок может перекрываться. -end note] Оценки A и B неопределенно секвенированы, когда либо A секвенирован до того, как B или B секвенированы до A, но не определено, что. [Примечание. Неопределенно оценки секвенирования не могут перекрываться, но либо могут быть выполнены в первую очередь. -end note]
Другими словами, порядок, вызываемый функциями, не определен. Это не означает, что «мы не знаем», это не означает, что «вы не можете это решить» - это означает, что он определяется как не имеющий определения; компилятор и процессор могут их заполнять в любом порядке.
Рассмотрим следующий пример:
int a[3];
void f1() { a[0] = 1; }
void f2() { a[1] = 2; }
void f3() { a[2] = 3; }
int main() {
f1(), f2(), f3();
}
В принципе язык не утверждает никаких требований при заказе на заявлении, как
std::cout << f1() << f2() << f3();
Ваш код не имеет точек последовательности (http://en.wikipedia.org/wiki/Sequence_point) между вызовами функции; вы можете определить порядок, который генерирует ваш компилятор, но он может вести себя по-разному на другом процессоре или на другом уровне оптимизации.
Если у вас есть изменяемые вызовы функций, как это, вам нужно вручную поднимать или добавлять разрывы:
std::cout << f1();
std::cout << f2();
std::cout << f3();
или
auto a1 = f1();
auto a2 = f2();
auto a3 = f3();
std::cout << a1 << a2 << a3;
Порядок оценки параметров функции не задан, см. здесь [здесь] (http://herbsutter.com/gotw/_102/) – davidhigh
У вас нет промежуточной точки последовательности между различными модификациями в 'j', поэтому порядок неопределен. –