Да, это требуется (как порядок оценки, так и короткое замыкание). В вашем примере, если все функции возвращают true, порядок вызовов строго из functionA, затем functionB и затем functionC. Используется для этого как
if(ptr && ptr->value) {
...
}
То же самое для оператора запятой:
// calls a, then b and evaluates to the value returned by b
// which is used to initialize c
int c = (a(), b());
Кто-то говорит, что между левым и правым операндами &&
, ||
, ,
и между первым и вторым / третьим операндами ?:
(условный оператор) является «точкой последовательности». Любые побочные эффекты полностью оцениваются до этого момента. Итак, это безопасно:
int a = 0;
int b = (a++, a); // b initialized with 1, and a is 1
Обратите внимание, что оператор запятой не следует путать с синтаксической запятой, используемой для разделения вещей:
// order of calls to a and b is unspecified!
function(a(), b());
Стандарт C ++ гласит: 5.14/1
:
Операторы && группируются слева направо. Оба операнда неявно преобразуются в тип bool (пункт 4).
Результат равен true, если оба операнда имеют значение true, в противном случае - false. В отличие от &, && гарантирует слева направо
оценка: второй операнд не оценивается, если первый операнд является ложным.
А в 5.15/1
:
|| оператор группы слева направо. Оба операнда неявно преобразуются в bool (пункт 4). Он возвращает true, если любой из его операндов равен true, и false в противном случае. В отличие от |, || гарантирует оценку слева направо; более того, второй операнд не оценивается, если первый операнд имеет значение true.
Это говорит для обоих рядом с:
Результатом является bool. Все побочные эффекты первого выражения, за исключением уничтожения временных (12.2), происходят до того, как вычислено второе выражение.
В дополнение к этому 1.9/18
говорит
При оценке каждого из выражений
a && b
a || b
a ? b : C
a , b
Используя встроенное значение операторов в этих выражениях (5.14, 5.15, 5.16, 5.18), после оценки первого выражения есть точка последовательности.