я только знаю i = i++;
является неопределенное поведение, но если есть две или более функций, вызываемых в выражение, и все функции одинаковы. Это не определено? Например:
int func(int a)
{
std::cout << a << std::endl;
return 0;
}
int main()
{
std::cout << func(0) + func(1) << std::endl;
return 0;
}
Поведение выражения func(0) + func(1)
определяется тем, что результатом будет сумма результатов, полученных путем вызова func
с параметром 0
а также func
с параметром 1
,
Однако порядок вызова функций, вероятно, зависит от реализации, хотя это может быть не указано. То есть компилятор может генерировать код, эквивалентный:
int a = func(0);
int b = func(1);
int result = a + b;
Или это может сгенерировать:
int a = func(1);
int b = func(0);
int result = a + b;
Это обычно не будет проблемой, если func
имеет побочные эффекты, которые зависят от порядка звонков.
std::cout << func(0) + func(1) << std::endl;
Будь функция вызова func(0)
или же func(1)
выполняется первым, зависит от реализации. После этого есть точка последовательности, и func(0) + func(1)
это выход.
Но по определению это не называется неопределенным поведением.
Поведение этой программы не не определено но это неопределенные, если мы посмотрим на проект стандарта C ++ раздел 1.9
Выполнение программы параграф 15 говорит (акцент мой):
Если не указано иное, вычисления операндов отдельных операторов и подвыражений отдельных выражений не являются последовательными. [Примечание: В выражении, которое оценивается более одного раза во время выполнения программы, непоследовательные и неопределенно последовательные оценки ее подвыражений не должны выполняться последовательно в различных оценках. — примечание конца] Вычисления значения операндов оператора секвенируются до вычисления значения результата оператора. Если побочный эффект на скаляр
Объект не секвенирован относительно другого побочного эффекта на тот же скалярный объект или вычисления значения с использованием значения того же скалярного объекта, поведение не определено.
и если мы проверим раздел 5.7
Аддитивные операторы который охватывает +
а также -
этот раздел не определяет порядок, поэтому он не упорядочен.
В этом случае func
имеет побочный эффект, так как он выводит на stdout
и поэтому порядок вывода будет зависеть от реализации и даже может измениться для последующих оценок.
Обратите внимание, что ;
заканчивается выражение выражения и раздел 6.2
Выражение выражение говорит:
[…] Все побочные эффекты от выражения выражения завершаются до выполнения следующего оператора. […]
поэтому, хотя порядок вызовов функций не определен, побочные эффекты каждого оператора завершаются до следующего.