Se tivermos três funções (foo, bar e baz) que são compostas assim ...
foo(bar(), baz())
Existe alguma garantia pelo padrão C ++ de que a barra será avaliada antes do baz?
Não, não existe essa garantia. Não é especificado de acordo com o padrão C ++.
Bjarne Stroustrup também diz isso explicitamente na seção 6.2.2 "The C ++ Programming Language" 3ª edição, com alguns argumentos:
Um código melhor pode ser gerado na ausência de restrições na ordem de avaliação da expressão
Embora tecnicamente isso se refira a uma parte anterior da mesma seção que diz que a ordem de avaliação das partes de uma expressão também não é especificada, ou seja,
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Não há ordem especificada para bar () e baz () - a única coisa que o padrão diz é que ambos serão avaliados antes de foo () ser chamado. Do padrão C ++, seção 5.2.2 / 8:
fonte
bar
, a seguir a linha 1 debaz
, a linha 2 debar
etc.), o que também é bom. :-)De [5.2.2] chamada de função,
Portanto, não há garantia de que
bar()
será executado antesbaz()
, apenas quebar()
ebaz()
será chamado antesfoo
.Observe também em [5] Expressões que:
então, mesmo que você perguntasse se
bar()
será executado antesbaz()
emfoo(bar() + baz())
, a ordem ainda não foi especificada.fonte
&
,&&
garante a avaliação da esquerda para a direita: o segundo operando não é avaliado se o primeiro operando forfalse
."C ++ 17 especifica a ordem de avaliação para operadores que não foram especificados até C ++ 17. Veja a pergunta Quais são as garantias de ordem de avaliação introduzidas pelo C ++ 17? Mas observe sua expressão
ainda tem ordem de avaliação não especificada.
fonte
Em C ++ 11, o texto relevante pode ser encontrado em 8.3.6 Argumentos padrão / 9 (Ênfase minha)
O mesmo palavreado também é usado pelo padrão C ++ 14 e pode ser encontrado na mesma seção .
fonte
Como outros já apontaram, a norma não fornece nenhuma orientação sobre a ordem de avaliação para este cenário específico. Essa ordem de avaliação é então deixada para o compilador, e o compilador pode ter uma garantia.
É importante lembrar que o padrão C ++ é realmente uma linguagem para instruir um compilador na construção de código de montagem / máquina. O padrão é apenas uma parte da equação. Onde o padrão é ambíguo ou é especificamente definido pela implementação, você deve recorrer ao compilador e entender como ele traduz as instruções C ++ em verdadeira linguagem de máquina.
Portanto, se a ordem de avaliação for um requisito, ou pelo menos importante, e ser compatível com compilador cruzado não é um requisito, investigue como seu compilador acabará por juntar isso, sua resposta pode estar aí. Observe que o compilador pode mudar sua metodologia no futuro
fonte