Lógica AND, OR: A avaliação da esquerda para a direita é garantida?

A avaliação da esquerda para a direita dos operadores lógicos ( && || ) é garantida?

Vamos dizer que eu tenho isso:

 SDL_Event event; if (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { // do stuff } } 

Isso é garantido para ser o mesmo que isso?

 SDL_Event event; if (SDL_PollEvent(&event) && event.type == SDL_QUIT) { // do stuff } 

Isso também pode ser muito importante, digamos que temos dois requisitos, a e b . O requisito a é muito mais provável de falhar do que b . Então é mais eficiente dizer if (a && b) que if (b && a) .

Sim, é garantido, caso contrário, esses operadores perderiam muito de sua utilidade.

Aviso importante : isso é válido apenas para o && and && || ; Se algum criminoso os sobrecarrega, eles são tratados como operadores binários sobrecarregados “regulares”, portanto, nesse caso, os dois operandos são sempre avaliados e, como sempre , em uma ordem não especificada. Por esta razão, nunca os sobrecarregue – isto quebra uma suposição extremamente importante sobre o stream de controle do programa.


Cotações padrão relevantes

Construído && e || ter garantido um comportamento de curto-circuito

§5.14 ¶1

Ao contrário de & , && garante a avaliação da esquerda para a direita: o segundo operando não é avaliado se o primeiro operando for false .

§5.15 ¶1

Ao contrário | || garante avaliação da esquerda para a direita; Além disso, o segundo operando não é avaliado se o primeiro operando é avaliado como true .

Se sobrecarregados, eles se comportam como operadores binários “regulares” (nenhum pedido de avaliação de curto-circuito ou garantido)

§13.5 ¶9

Os operadores não mencionados explicitamente nas subcláusulas 13.5.3 a 13.5.7 agem como operadores ordinários unários e binários obedecendo às regras de 13.5.1 ou 13.5.2.

e && e || não são mencionados explicitamente nestas sub-cláusulas, então o §13.5.2 regular contém:

§13.5.2 ¶1

Um operador binário deve ser implementado por uma function de membro não estático (9.3) com um parâmetro ou por uma function não membro com dois parâmetros. Assim, para qualquer operador binário @ , x@y pode ser interpretado como x.operator@(y) ou operator@(x,y) .

sem nenhuma provisão especial para avaliar somente um lado ou em uma ordem particular.

(todas as citações do padrão C ++ 11)