Este comportamiento tiene que ver con la forma en que maneja sonido metálico pre decremento en comparación con operadores binarios como sub-y-asignar. Tenga en cuenta que intentaré explicar, a nivel clang, por qué ve este comportamiento. No sé por qué fue elegido para implementarlo de esta manera, pero supongo que fue solo por la facilidad de implementación.
Todas las funciones que hago referencia aquí se pueden encontrar en la clase ScalarExprEmitter
dentro de lib/CodeGen/CGExprScalar.cpp
.
Pre/post decremento/incremento se manejan de la misma manera por la función EmitScalarPrePostIncDec
: un add
instrucción LLVM se emite ya sea con 1
o -1
como segundo argumento, en función de la expresión de ser un incremento o un decremento respectivamente.
Por lo tanto,
--x
va a terminar, en el LLVM IR, como algo parecido
add i32 %x, -1
que, naturalmente, se traduce en x86 como algo parecido
add $0xffffffff, %ecx
Los operadores binarios, por otro lado, se manejan de manera diferente. En su caso,
x -= 1
estará a cargo de EmitCompoundAssign
que a su vez llama a EmitSub
. Se emitirá algo como el siguiente LLVM IR:
sub i32 %x, 1
Probablemente sea solo la implementación, y podría cambiar con el nivel de optimización. Lo que es más interesante es que no usa 'dec', que puede ser una optimización porque' dec' no cambia tantas banderas de estado, por lo que depende de las instrucciones anteriores. – ughoavgfhw
gcc produce el mismo código tanto para 'x -' como 'x = -1' usando' subl'. Curiosamente, usa 'xorl' si habilito' -O3'. –
No hay ninguna ventaja, y no hay ninguna desventaja. Ambos tienen 3 bytes y tienen las mismas características de rendimiento. – harold