速記ではありません。
+=
シンボルは、1970年代にC言語で登場し、 - 「スマートアセンブラ」のCアイデアとは明らかに異なるマシン命令とadressingモードに対応しています。
「i=i+1
」、「」、"i+=1
「」のようなもの++i
は、抽象的なレベルでは同じ効果を生み出しますが、低レベルではプロセッサーの異なる動作方法に対応します。
特にこれら3つの式は、i
変数がCPUレジスタに保存されているメモリアドレスにあると仮定し(名前を付けましょうD
-「intへのポインタ」と考えてください)、プロセッサのALUはパラメータを受け取り、結果を「アキュムレータ」(Aと呼びましょう-intと考えてください)。
これらの制約により(その期間のすべてのマイクロプロセッサで非常に一般的)、翻訳はほとんどの場合
;i = i+1;
MOV A,(D); //Move in A the content of the memory whose address is in D
ADD A, 1; //The addition of an inlined constant
MOV (D) A; //Move the result back to i (this is the '=' of the expression)
;i+=1;
ADD (D),1; //Add an inlined constant to a memory address stored value
;++i;
INC (D); //Just "tick" a memory located counter
最初の方法は最適ではありませんが、定数(ADD A, B
またはADD A, (D+x)
)の代わりに変数を使用して操作する場合、またはより複雑な式を変換する場合(スタック内のプッシュ低優先度操作ですべてが沸騰し、高優先度を呼び出し、ポップする場合)すべての引数が削除されるまで繰り返します)。
2番目は「ステートマシン」のより典型的なものです。「式を評価する」のではなく、「値を操作する」のです。これらの種類の命令は、より複雑な表現が必要な場所では使用i = 3*i + i-2
できませんi
。
3番目の(さらに単純な)手法では、「加算」という考えさえ考慮されていませんが、カウンターに対してより「プリミティブ」な(計算的な意味での)回路を使用しています。レジスタを後付けしてカウンタにするために必要な組み合わせネットワークは小さく、したがって全加算器のものよりも高速であるため、命令は短絡され、ロードが速く、すぐに実行されます。
コンパイラーの最適化を可能にする最新のコンパイラー(現在はCを参照)では、利便性に基づいて対応関係を入れ替えることができますが、セマンティクスには概念的な違いがあります。
x += 5
手段
しかし、x = x + 5
意味:
- x + 5を評価する
- xで識別される場所を見つける
- xをアキュムレーターにコピーします
- アキュムレーターに5を追加します
- 結果をxに保存します
- xで識別される場所を見つける
- アキュムレーターをそれにコピーします
もちろん、最適化は
- 「xの検索」に副作用がない場合、2つの「検索」を1回実行できます(xはポインタレジスタに格納されたアドレスになります)
- ADDが
&x
アキュムレータの代わりに適用される場合、2つのコピーは省略できます。
したがって、最適化されたコードが一致するようにしx += 5
ます。
ただし、これは「xを検出」に副作用がない場合にのみ可能です。
*(x()) = *(x()) + 5;
そして
*(x()) += 5;
以来、意味的に異なっているx()
(了解が副作用x()
の周りに奇妙なことをやって返す関数であるint*
)を2回または一回生成されます。
間の等価性x = x + y
とは、x += y
原因特定の場合には、従ってある+=
と=
直接L値に適用されます。
Pythonに移行するために、Cから構文を継承しましたが、インタープリター言語での実行の前に翻訳/最適化がないため、物事は必ずしもそれほど密接に関連しているわけではありません(解析ステップが1つ少ないため)。ただし、インタープリターは3種類の式の異なる実行ルーチンを参照でき、式の形成方法と評価コンテキストに応じて異なるマシンコードを利用できます。
詳細が好きな人のために...
すべてのCPUにはALU(算術論理ユニット)があります。ALUは、本質的には、命令のオペコードに応じてレジスタおよび/またはメモリに入力および出力が「プラグイン」される組み合わせネットワークです。
バイナリ演算は通常、「どこかで」入力が行われるアキュムレータレジスタの修飾子として実装されます。どこかは、命令フロー自体の内部(マニフェスト定数:ADD A 5に一般的)-別のレジストリ内(式の計算に一般的)一時的:例:ADD AB)-メモリ内で、レジスタで指定されたアドレスで(例:ADD A(H)をフェッチするデータの例)-この場合、Hは逆参照ポインターのように機能します。
この擬似コードでx += 5
は、
ADD (X) 5
しばらくはx = x+5
あります
MOVE A (X)
ADD A 5
MOVE (X) A
つまり、x + 5は、後で割り当てられる一時的なものを提供します。x += 5
xで直接動作します。
実際の実装は、プロセッサの実際の命令セットに依存します。ADD (.) c
オペコードがない場合、最初のコードは2番目になります。
そのようなオペコードがあり、最適化が有効になっている場合、2番目の式は、逆方向の移動を排除してレジスタオペコードを調整した後、最初の式になります。
x += 5
よりもCLRの方が効率的x = x + 5
ですか?それとも、あなたが示唆するように、それは本当に単なる構文糖ですか?