Так, це вимагає (як порядок оцінки, так і коротке замикання). У вашому прикладі, якщо всі функції повертаються як істинні, порядок викликів суворо функціонуєA, а потім функціяB, а потім функціяC. Використовується для подібного
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). Результат вірний, якщо обидва операнди істинні та помилкові в іншому випадку. На відміну від &, && гарантує оцінку зліва направо: другий операнд не оцінюється, якщо перший операнд помилковий.
І в 5.15/1
:
|| групи операторів зліва направо. Обидва операнди неявно перетворюються на bool (п. 4). Він повертає true, якщо будь-який з його операндів є істинним, а false - іншим. На відміну від |, || гарантує оцінку зліва направо; крім того, другий операнд не оцінюється, якщо перший операнд оцінюється як істинний.
Він говорить і для тих, хто поруч із цими:
Результат - бул. Всі побічні ефекти першого вираження, за винятком руйнування темпорацій (12.2), трапляються до того, як буде оцінено другий вираз.
Крім того, 1.9/18
каже
В оцінці кожного з виразів
a && b
a || b
a ? b : C
a , b
використовуючи вбудоване значення операторів у цих виразах (5.14, 5.15, 5.16, 5.18), після оцінки першого виразу є точка послідовності.