Pertama, jawaban Henk dan Olivier benar; Saya ingin menjelaskannya dengan cara yang sedikit berbeda. Secara khusus, saya ingin membahas poin yang Anda buat ini. Anda memiliki kumpulan pernyataan ini:
int k = 10;
int c = 30;
k += c += k += c;
Dan Anda kemudian salah menyimpulkan bahwa ini harus memberikan hasil yang sama seperti kumpulan pernyataan ini:
int k = 10;
int c = 30;
k += c;
c += k;
k += c;
Adalah informatif untuk mengetahui bagaimana Anda melakukan kesalahan itu, dan bagaimana melakukannya dengan benar. Cara yang tepat untuk memecahnya adalah seperti ini.
Pertama, tulis ulang + = terluar
k = k + (c += k += c);
Kedua, tulis ulang + terluar. Saya harap Anda setuju bahwa x = y + z harus selalu sama dengan "evaluasi y untuk sementara, evaluasi z ke sementara, jumlahkan sementara, berikan jumlah ke x" . Jadi mari kita buat itu sangat eksplisit:
int t1 = k;
int t2 = (c += k += c);
k = t1 + t2;
Pastikan itu jelas, karena ini adalah langkah yang Anda keliru . Saat memecah operasi yang rumit menjadi operasi yang lebih sederhana, Anda harus memastikan bahwa Anda melakukannya dengan lambat dan hati - hati serta tidak melewatkan langkah-langkah . Melompati langkah adalah saat kita membuat kesalahan.
Oke, sekarang uraikan tugas ke t2, lagi, perlahan dan hati-hati.
int t1 = k;
int t2 = (c = c + (k += c));
k = t1 + t2;
Tugas akan menetapkan nilai yang sama ke t2 seperti yang ditetapkan ke c, jadi katakanlah:
int t1 = k;
int t2 = c + (k += c);
c = t2;
k = t1 + t2;
Bagus. Sekarang hancurkan baris kedua:
int t1 = k;
int t3 = c;
int t4 = (k += c);
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Bagus, kami membuat kemajuan. Pecahkan tugas ke t4:
int t1 = k;
int t3 = c;
int t4 = (k = k + c);
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Sekarang hancurkan baris ketiga:
int t1 = k;
int t3 = c;
int t4 = k + c;
k = t4;
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Dan sekarang kita bisa melihat semuanya:
int k = 10;
int c = 30;
int t1 = k;
int t3 = c;
int t4 = k + c;
k = t4;
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Jadi setelah kita selesai, k adalah 80 dan c adalah 70.
Sekarang mari kita lihat bagaimana ini diterapkan di IL:
int t1 = k;
int t3 = c;
is implemented as
ldloc.0
ldloc.1
Sekarang ini agak rumit:
int t4 = k + c;
k = t4;
is implemented as
ldloc.0
ldloc.1
add
dup
stloc.0
Kami bisa menerapkan di atas sebagai
ldloc.0
ldloc.1
add
stloc.0
ldloc.0
tetapi kami menggunakan trik "dup" karena itu membuat kode lebih pendek dan membuatnya lebih mudah di jitter, dan kami mendapatkan hasil yang sama. Secara umum, generator kode C # mencoba untuk menyimpan temporer "singkat" di stack sebanyak mungkin. Jika Anda merasa lebih mudah untuk mengikuti IL dengan ephemerals lebih sedikit, giliran optimasi off , dan kode generator akan kurang agresif.
Kita sekarang harus melakukan trik yang sama untuk mendapatkan c:
int t2 = t3 + t4;
c = t2;
is implemented as:
add
dup
stloc.1
dan akhirnya:
k = t1 + t2;
is implemented as
add
stloc.0
Karena kami tidak memerlukan jumlah untuk hal lain, kami tidak menipunya. Tumpukan sekarang kosong, dan kita berada di akhir pernyataan.
Moral dari cerita ini adalah: ketika Anda mencoba untuk memahami program yang rumit, selalu hancurkan operasi satu per satu . Jangan mengambil jalan pintas; mereka akan menyesatkan Anda.