Questo comportamento ha a che fare con il modo in cui gestisce clangore pre- decrementa rispetto agli operatori binari come sub-and-assign. Nota che cercherò semplicemente di spiegare, a livello di clang, perché vedi questo comportamento. Non so perché è stato scelto per implementarlo in questo modo ma immagino sia stato solo per facilità di implementazione.
Tutte le funzioni di cui faccio riferimento sono reperibili nella classe ScalarExprEmitter
all'interno di lib/CodeGen/CGExprScalar.cpp
.
pre/post decremento/incremento sono tutti trattati allo stesso modo dalla funzione EmitScalarPrePostIncDec
: un add
istruzione LLVM viene emessa sia con 1
o -1
come secondo argomento, a seconda della un'espressione sia un incremento o un decremento rispettivamente.
Pertanto,
--x
finirà, nel LLVM IR, come qualcosa di simile
add i32 %x, -1
che, del tutto naturalmente, si traduce in 86 come qualcosa di simile
add $0xffffffff, %ecx
Gli operatori binari, d'altra parte, sono tutti gestiti in modo diverso. Nel tuo caso,
x -= 1
saranno trattati da EmitCompoundAssign
, che a sua volta chiama EmitSub
. Viene emesso qualcosa come il seguente LLVM IR:
sub i32 %x, 1
Probabilmente è solo l'implementazione e potrebbe cambiare con il livello di ottimizzazione. La cosa più interessante è che non usa 'dec', che può essere un'ottimizzazione perché' dec' non cambia tanti flag di stato, quindi dipende dalle istruzioni precedenti. – ughoavgfhw
gcc produce lo stesso codice per entrambi 'x -' e 'x = -1' usando' subl'. È interessante notare che usa 'xorl' se abilito' -O3'. –
Non c'è alcun vantaggio e non ci sono svantaggi. Entrambi sono 3 byte e hanno le stesse caratteristiche di prestazione. – harold