Avaliação de curto-circuito e efeitos colaterais

OK, eu estou um pouco envergonhado de fazer essa pergunta, mas eu só quero ter certeza …

Sabe-se que C usa avaliação de curto-circuito em expressões booleanas:

int c = 0; if (c && func(c)) { /* whatever... */ } 

Nesse exemplo, func(c) não é chamado porque c avaliado como 0 . Mas e quanto ao exemplo mais sofisticado em que os efeitos colaterais da comparação mudariam a variável que está sendo comparada a seguir? Como isso:

 int c; /* this is not even initialized... */ if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ } 

A function canInitWithSomeValue retorna true e altera o valor no ponteiro dado em caso de sucesso. É garantido que as comparações subsequentes ( c == SOMETHING neste exemplo) usam o valor definido por canInitWithSomeValue(&c) ?

Não importa quão pesado otimizações o compilador usa?

É garantido que as comparações subsequentes (c == SOMETHING neste exemplo) usam o valor definido por canInitWithSomeValue (& c)?

Sim. Porque existe um ponto de sequência

Entre avaliação dos operandos esquerdo e direito do && (AND lógico), || (OR lógica) e operadores de vírgula. Por exemplo, na expressão *p++ != 0 && *q++ != 0 , todos os efeitos colaterais da sub-expressão * p ++! = 0 são completados antes de qualquer tentativa de access a q.


Um ponto de seqüência define qualquer ponto na execução de um programa de computador no qual é garantido que todos os efeitos colaterais de avaliações anteriores terão sido executados, e nenhum efeito colateral de avaliações subseqüentes foi realizado.

Sim. Porque tanto && e || operador também são chamados de pontos de seqüência. Este último define quando os efeitos colaterais de uma operação anterior devem estar completos e os do lado seguinte não devem ter começado.

A avaliação dentro da condição composta da declaração if é estritamente da esquerda para a direita. A única circunstância sob a qual o segundo teste em seu if seria otimizado é se o compilador puder determinar com 100% de certeza que o primeiro é igual a false.