Eu tenho o seguinte código:
#include <stdio.h>
int main(int argc, char **argv) {
int i = 0;
(i+=10)+=10;
printf("i = %d\n", i);
return 0;
}
Se eu tentar compilá-lo como uma fonte C usando gcc, recebo um erro:
error: lvalue required as left operand of assignment
Mas se eu compilá-lo como uma fonte C ++ usando g ++, não recebo nenhum erro e quando executo o executável:
i = 20
Por que o comportamento diferente?
Respostas:
A semântica dos operadores de atribuição compostos é diferente em C e C ++:
Padrão C99, 6.5.16, parte 3:
Em C ++ 5.17.1:
EDITAR: O comportamento de
(i+=10)+=10
em C ++ é indefinido em C ++ 98, mas bem definido em C ++ 11. Veja esta resposta à pergunta da NPE para as partes relevantes dos padrões.fonte
(i+=10)+=10
é um comportamento indefinido em C ++, consulte a resposta @aix.int f(int &y); f(x += 10);
- passar uma referência à variável modificada em uma função.Além de ser um código C inválido, a linha
resultaria em um comportamento indefinido em C e C ++ 03 porque modificaria
i
duas vezes entre os pontos de sequência.Por que é permitido compilar em C ++:
O mesmo parágrafo diz que
Isso sugere que no C ++ 11, a expressão não tem mais comportamento indefinido.
fonte
i
que não são sequenciadas.i = j+=1
o resultado seria um valor indeterminado. Do mesmo parágrafo, você cita "Em todos os casos, a atribuição é sequenciada após o cálculo do valor dos operandos direito e esquerdo e antes do cálculo do valor da expressão de atribuição." Portanto,(i+=10)+=10
está bem definido para fazeri += 10; i += 10;
. Por outro lado,(i+=10)+=(i+=10)
é UB.