Ordem de avaliação e comportamento indefinido
Falando no contexto do padrão C ++ 11 (que não tem mais um conceito de pontos de seqüência, como você sabe), eu quero entender como dois exemplos mais simples são definidos.
int i = 0;
i = i++; // #0
i = ++i; // #1
Existem dois tópicos sobre SO que explicam esses exemplos no contexto do C ++ 11.Aqui foi dito que#0
invoca o UB e#1
está bem definido.Aqui Foi dito que ambos os exemplos são indefinidos. Essa ambigüidade me confunde muito. Eu li isso bem estruturadoreferência já três vezes, mas o tópico parece ser muito complicado para mim.
.
Vamos analisar o exemplo#0
: i = i++;
.
Cotações correspondentes são:
O cálculo do valor dos operadores embutidos de pós-incremento e pós-decaimento é seqüenciado antes de seu efeito colateral.
O efeito colateral (modificação do argumento à esquerda) do operador de atribuição interno e de todos os operadores de atribuição compostos internos é sequenciado após o cálculo do valor (mas não dos efeitos colaterais) dos argumentos esquerdo e direito e é sequenciado antes o cálculo do valor da expressão de atribuição (isto é, antes de retornar a referência ao objeto modificado)
Se um efeito colateral em um objeto escalar é desassociado em relação a outro efeito colateral no mesmo objeto escalar, o comportamento é indefinido.
Pelo que entendi, o efeito colateral do operador de atribuição não é sequenciado com os efeitos colaterais dos argumentos esquerdo e direito. Assim, o efeito colateral do operador de atribuição não é sequenciado com os efeitos colateraisi++
. assim#0
invoca um UB.
.
Vamos analisar o exemplo#1
: i = ++i;
.
Cotações correspondentes são:
O efeito colateral dos operadores pré-incremento e pré-incremento embutidos é sequenciado antes de seu cálculo de valor (regra implícita devido à definição como atribuição composta)
O efeito colateral (modificação do argumento à esquerda) do operador de atribuição interno e de todos os operadores de atribuição compostos internos é sequenciado após o cálculo do valor (mas não dos efeitos colaterais) dos argumentos esquerdo e direito e é sequenciado antes o cálculo do valor da expressão de atribuição (isto é, antes de retornar a referência ao objeto modificado)
Se um efeito colateral em um objeto escalar é desassociado em relação a outro efeito colateral no mesmo objeto escalar, o comportamento é indefinido.
Eu não consigo ver como esse exemplo é diferente do#0
. Isto parece ser um UB para mim pela mesma razão que#0
. O efeito colateral da atribuição não é seqüenciado com o efeito colateral de++i
. Parece ser um UB. O tópico desejado acima diz que está bem definido. Por quê?
.
Questão: como posso aplicar regras citadas para determinar o UB dos exemplos. Uma explicação tão simples quanto possível seria muito apreciada. Obrigado!