Tecnicamente, no geral, esse é o comportamento indefinido .
Mas, existem dois aspectos importantes para a resposta.
A declaração do código:
std::cout << a++ << a;
é avaliado como:
std::operator<<(std::operator<<(std::cout, a++), a);
O padrão não define a ordem de avaliação dos argumentos para uma função.
Ou então:
std::operator<<(std::cout, a++)
é avaliado primeiro ou
a
é avaliado primeiro ou
- pode ser qualquer ordem definida pela implementação.
Este pedido não é especificado [Ref 1] de acordo com o padrão.
[Ref 1] C ++ 03 5.2.2 Chamada de função
Para 8
A ordem de avaliação dos argumentos não é especificada . Todos os efeitos colaterais das avaliações de expressão de argumento têm efeito antes que a função seja inserida. A ordem de avaliação da expressão pós-fixada e da lista de expressões de argumento não é especificada.
Além disso, não há ponto de sequência entre a avaliação de argumentos para uma função, mas um ponto de sequência existe apenas após a avaliação de todos os argumentos [Ref 2] .
[Ref 2] C ++ 03 1.9 Execução do programa [introdução.execução]:
Parágrafo 17:
Ao chamar uma função (seja a função embutida ou não), há um ponto de sequência após a avaliação de todos os argumentos da função (se houver) que ocorre antes da execução de quaisquer expressões ou instruções no corpo da função.
Observe que, aqui o valor de c
está sendo acessado mais de uma vez sem um ponto de sequência interveniente, em relação a isso o padrão diz:
[Ref 3] C ++ 03 5 Expressões [expr]:
Para 4:
....
Entre o ponto de sequência anterior e seguinte, um objeto escalar deve ter seu valor armazenado modificado no máximo uma vez pela avaliação de uma expressão. Além disso, o valor anterior deve ser acessado apenas para determinar o valor a ser armazenado . Os requisitos deste parágrafo devem ser atendidos para cada ordenação permitida das subexpressões de uma expressão completa; caso contrário, o comportamento é indefinido .
O código se modifica c
mais de uma vez sem ponto de sequência intermediário e não está sendo acessado para determinar o valor do objeto armazenado. Esta é uma violação clara da cláusula acima e, portanto, o resultado conforme exigido pela norma é Comportamento indefinido [Ref 3] .