De acordo com cppreference :
“Ao chamar uma função (seja a função inline ou não, e seja ou não usada a sintaxe de chamada de função explícita), cada cálculo de valor e efeito colateral associado a qualquer expressão de argumento, ou com a expressão pós-fixada que designa a função chamada, é sequenciado antes da execução de cada expressão ou declaração no corpo da função chamada”.
Alguém poderia explicar o que significa: “ou com a expressão pós-fixada designando a função chamada” e dar um exemplo.
O que é uma "expressão pós-fixada"?
A precedência de operadores C++ não é muito intuitiva no nível de sintaxe. Os itens com maior precedência são coisas como identificadores (nomes de variáveis/funções) ou constantes inteiras (como
123
). Eles pertencem ao grupo primary expressions .A segunda maior precedência é o grupo de operadores que são operadores unários pós-fixados, talvez as coisas mais óbvias como
i++
onde o++
é o operador de incremento pós-fixado. Mas outros operadores como subscrição de array[ ]
e chamada de função( )
também são operadores pós-fixados.Para chamadas de função especificamente, a sintaxe formal é como (C++20 7.6.1):
Então, neste caso, "postfix" contraintuitivamente se refere a tudo à esquerda da
( )
chamada de função, já que o operador de chamada de função é um dos operadores postfix. E se ignorarmos cppreference e formos ler o padrão real, então ele diz (C++20 7.6.1.2 §8):Ordem de avaliação durante chamadas de função
Vamos preparar um exemplo com uma matriz de ponteiros de função
farr
:E então chamamos uma função usando esse array:
Então a "expressão pós-fixada"
farr[i++]
contém um efeito colaterali++
(ou pode conter um cálculo de valori
). O que sua citação não menciona é como essa parte é sequenciada em relação à avaliação do argumento(i++)
.A parte do padrão que eu citei, no entanto. "A expressão pós-fixada é sequenciada antes de cada expressão na lista de expressões". Então a esquerda
i++
é executada antes da direita e isso é bem definido.No entanto, seu texto citado está apenas dizendo de forma um tanto inútil que tanto a
farr[i++]
(expressão pós-fixada) quanto a(i++)
(expressão de argumento) são sequenciadas antesdo_something(i++);
dentro do corpo da função. Da nota no padrão citado "Todos os efeitos colaterais das avaliações de argumento são sequenciados antes que a função seja inserida".Esta é a expressão à esquerda dos parênteses na expressão de chamada de função.
Por exemplo:
Aqui, a expressão pós-fixada da expressão de chamada de função
(i++, f)(i)
é(i++, f)
.A citação diz que isso
(i++, f)
é totalmente avaliado, incluindo quaisquer efeitos colaterais, antes deif(i) i++;
entrar na chamada paraf
, o que significa que não haverá nenhum comportamento indefinido e o programa tem garantia de retornar2
.