ฉันคิดว่าส่วนนี้ของร่างมาตรฐานเกี่ยวกับลำดับการประเมินมีความเกี่ยวข้อง:
1.9 การดำเนินการโปรแกรม
...
- ยกเว้นในกรณีที่ระบุไว้การประเมินค่าตัวถูกดำเนินการของแต่ละตัวดำเนินการและนิพจน์ย่อยของนิพจน์แต่ละรายการจะไม่ได้รับผลกระทบ การคำนวณค่าของตัวถูกดำเนินการของตัวดำเนินการจะเรียงลำดับก่อนการคำนวณค่าของผลลัพธ์ของตัวดำเนินการ หากผลข้างเคียงที่มีต่อวัตถุสเกลาร์ไม่สัมพันธ์กับผลข้างเคียงอื่นที่มีต่อวัตถุสเกลาร์เดียวกันหรือการคำนวณค่าโดยใช้ค่าของวัตถุสเกลาร์เดียวกันและอาจไม่เกิดขึ้นพร้อมกันพฤติกรรมจะไม่ถูกกำหนด
และนอกจากนี้ยังมี:
5.2.2 การเรียกใช้ฟังก์ชัน
...
- [หมายเหตุ: การประเมินของนิพจน์ postfix และอาร์กิวเมนต์จะไม่สัมพันธ์กัน ผลข้างเคียงทั้งหมดของการประเมินอาร์กิวเมนต์จะถูกจัดลำดับก่อนที่จะป้อนฟังก์ชัน - หมายเหตุท้าย]
ดังนั้นสำหรับสายของคุณc.meth1(&nu).meth2(nu);
ให้พิจารณาสิ่งที่เกิดขึ้นในโอเปอเรเตอร์ในแง่ของตัวดำเนินการเรียกฟังก์ชันสำหรับการเรียกครั้งสุดท้ายเพื่อmeth2
ให้เราเห็นรายละเอียดอย่างชัดเจนในนิพจน์ postfix และอาร์กิวเมนต์nu
:
operator()(c.meth1(&nu).meth2, nu);
การประเมินของนิพจน์ postfix และอาร์กิวเมนต์สำหรับการเรียกใช้ฟังก์ชันสุดท้าย (เช่นนิพจน์ postfix c.meth1(&nu).meth2
และnu
) จะไม่สัมพันธ์กันตามกฎการเรียกฟังก์ชันข้างต้น ดังนั้นผลข้างเคียงของการคำนวณนิพจน์ postfix บนวัตถุสเกลาร์ar
จะไม่สัมพันธ์กับการประเมินอาร์กิวเมนต์nu
ก่อนการmeth2
เรียกใช้ฟังก์ชัน ตามกฎการทำงานของโปรแกรมด้านบนนี่คือพฤติกรรมที่ไม่ได้กำหนดไว้
กล่าวอีกนัยหนึ่งก็คือไม่มีข้อกำหนดสำหรับคอมไพลเลอร์ในการประเมินnu
อาร์กิวเมนต์ของการmeth2
เรียกหลังจากการmeth1
โทร - มีอิสระที่จะถือว่าไม่มีผลข้างเคียงที่จะmeth1
ส่งผลต่อการnu
ประเมินผล
รหัสแอสเซมบลีที่ผลิตโดยด้านบนประกอบด้วยลำดับต่อไปนี้ในmain
ฟังก์ชัน:
- ตัวแปร
nu
ถูกจัดสรรบนสแต็กและเริ่มต้นด้วย 0
- การลงทะเบียน (
ebx
ในกรณีของฉัน) ได้รับสำเนาค่าของnu
- ที่อยู่ของ
nu
และc
โหลดลงในรีจิสเตอร์พารามิเตอร์
meth1
ถูกเรียก
- รีจิสเตอร์ค่าส่งคืนและค่าแคชก่อนหน้านี้ของ
nu
ในebx
รีจิสเตอร์ถูกโหลดลงในรีจิสเตอร์พารามิเตอร์
meth2
ถูกเรียก
ในขั้นตอนที่ 5 เหนือคอมไพเลอร์อนุญาตให้ใช้ค่าแคชของ nu
จากขั้นตอนที่ 2 meth2
จะเป็นอีกครั้งที่ใช้ในการเรียกฟังก์ชั่น ในที่นี้จะไม่คำนึงถึงความเป็นไปได้ที่nu
อาจมีการเปลี่ยนแปลงโดยการเรียกร้องให้meth1
- 'พฤติกรรมที่ไม่ได้กำหนด' ในการดำเนินการ
หมายเหตุ:คำตอบนี้มีการเปลี่ยนแปลงในเนื้อหาจากรูปแบบเดิม คำอธิบายเริ่มต้นของฉันในแง่ของผลข้างเคียงของการคำนวณตัวถูกดำเนินการที่ไม่ได้รับการจัดลำดับก่อนที่จะเรียกฟังก์ชันสุดท้ายไม่ถูกต้องเนื่องจากเป็น ปัญหาคือความจริงที่ว่าการคำนวณของตัวถูกดำเนินการเองนั้นมีการเรียงลำดับอย่างไม่แน่นอน