Menurut saya, bagian dari draf standar mengenai urutan evaluasi ini relevan:
1.9 Eksekusi Program
...
- Kecuali jika disebutkan, evaluasi operan operator individu dan subekspresi ekspresi individu tidak diurutkan. Perhitungan nilai operan operator diurutkan sebelum perhitungan nilai hasil operator. Jika efek samping pada objek skalar tidak diurutkan secara relatif terhadap efek samping lain pada objek skalar yang sama atau penghitungan nilai menggunakan nilai objek skalar yang sama, dan keduanya tidak berpotensi bersamaan, perilakunya tidak ditentukan
dan juga:
5.2.2 Panggilan fungsi
...
- [Catatan: Evaluasi ekspresi postfix dan argumen semuanya tidak diurutkan relatif satu sama lain. Semua efek samping evaluasi argumen diurutkan sebelum fungsi dimasukkan - catatan akhir]
Jadi untuk baris Anda c.meth1(&nu).meth2(nu);
, pertimbangkan apa yang terjadi di operator dalam hal operator pemanggilan fungsi untuk panggilan terakhir ke meth2
, jadi kita dengan jelas melihat perincian ke dalam ekspresi dan argumen postfix nu
:
operator()(c.meth1(&nu).meth2, nu);
The evaluasi dari ekspresi postfix dan argumen untuk final panggilan fungsi (yaitu ekspresi postfix c.meth1(&nu).meth2
dan nu
) yang relatif unsequenced satu sama lain sesuai dengan fungsi panggilan aturan di atas. Oleh karena itu, efek samping dari penghitungan ekspresi postfix pada objek skalar ar
tidak diurutkan secara relatif terhadap evaluasi argumen nu
sebelum meth2
pemanggilan fungsi. Dengan aturan eksekusi program di atas, ini adalah perilaku yang tidak ditentukan.
Dengan kata lain, tidak ada persyaratan bagi kompilator untuk mengevaluasi nu
argumen meth2
panggilan setelah meth1
panggilan - itu bebas untuk mengasumsikan tidak ada efek samping dari meth1
mempengaruhi nu
evaluasi.
Kode assembly yang dihasilkan di atas berisi urutan main
fungsi berikut:
- Variabel
nu
dialokasikan pada stack dan diinisialisasi dengan 0.
- Register (
ebx
dalam kasus saya) menerima salinan nilainu
- Alamat
nu
dan c
dimuat ke register parameter
meth1
disebut
- Nilai kembali mendaftar dan nilai yang sebelumnya cache dari
nu
dalam ebx
register dimuat ke register parameter
meth2
disebut
Secara kritis, pada langkah 5 di atas compiler memungkinkan nilai yang di-cache nu
dari langkah 2 untuk digunakan kembali dalam pemanggilan fungsi ke meth2
. Di sini mengabaikan kemungkinan yang nu
mungkin telah diubah oleh ajakan untuk meth1
- 'perilaku yang tidak ditentukan' dalam tindakan.
CATATAN: Jawaban ini telah berubah substansi dari bentuk aslinya. Penjelasan awal saya dalam hal efek samping komputasi operan tidak diurutkan sebelum pemanggilan fungsi terakhir tidak benar, karena memang demikian. Masalahnya adalah fakta bahwa penghitungan operan itu sendiri diurutkan secara tidak pasti.