เทคนิคทั้งหมดนี้เป็นพฤติกรรมที่ไม่ได้กำหนด
แต่มีสองประเด็นสำคัญสำหรับคำตอบ
คำสั่งรหัส:
std::cout << a++ << a;
ได้รับการประเมินเป็น:
std::operator<<(std::operator<<(std::cout, a++), a);
มาตรฐานไม่ได้กำหนดลำดับของการประเมินอาร์กิวเมนต์ให้กับฟังก์ชัน
ดังนั้น:
std::operator<<(std::cout, a++)
ได้รับการประเมินก่อนหรือ
a
ได้รับการประเมินก่อนหรือ
- อาจเป็นคำสั่งที่กำหนดไว้สำหรับการนำไปใช้งาน
คำสั่งซื้อนี้ไม่ระบุ[Ref 1]ตามมาตรฐาน
[Ref 1] C ++ 03 5.2.2 การเรียกใช้ฟังก์ชัน
ย่อหน้าที่ 8
ลำดับของการประเมินข้อโต้แย้งไม่ได้ระบุไว้ ผลข้างเคียงทั้งหมดของการประเมินนิพจน์อาร์กิวเมนต์จะมีผลก่อนป้อนฟังก์ชัน ลำดับของการประเมินนิพจน์ postfix และรายการนิพจน์อาร์กิวเมนต์ไม่ได้ระบุไว้
นอกจากนี้ไม่มีจุดลำดับระหว่างการประเมินผลของการขัดแย้งกับฟังก์ชัน แต่จุดลำดับที่มีอยู่เฉพาะหลังจากการประเมินผลของการขัดแย้งทั้งหมด[Ref 2]
[Ref 2] C ++ 03 1.9 การเรียกใช้โปรแกรม [intro.execution]:
ย่อหน้าที่ 17:
เมื่อเรียกใช้ฟังก์ชัน (ไม่ว่าฟังก์ชันจะเป็นแบบอินไลน์หรือไม่ก็ตาม) จะมีจุดลำดับหลังจากการประเมินอาร์กิวเมนต์ของฟังก์ชันทั้งหมด (ถ้ามี) ซึ่งเกิดขึ้นก่อนที่จะเรียกใช้นิพจน์หรือคำสั่งใด ๆ ในเนื้อหาของฟังก์ชัน
โปรดทราบว่านี่คือค่าของc
การเข้าถึงมากกว่าหนึ่งครั้งโดยไม่มีจุดลำดับการแทรกแซงเกี่ยวกับเรื่องนี้มาตรฐานกล่าวว่า:
[Ref 3] C ++ 03 5 นิพจน์ [expr]:
ย่อหน้าที่ 4:
....
ระหว่างจุดลำดับก่อนหน้าและลำดับถัดไปวัตถุสเกลาร์จะต้องมีการแก้ไขค่าที่เก็บไว้มากที่สุดในครั้งเดียวโดยการประเมินนิพจน์ นอกจากนี้ค่าก่อนหน้าจะถูกเข้าถึงเพื่อกำหนดค่าที่จะจัดเก็บเท่านั้น ต้องปฏิบัติตามข้อกำหนดของย่อหน้านี้สำหรับแต่ละลำดับที่อนุญาตของนิพจน์ย่อยของนิพจน์แบบเต็ม มิฉะนั้นพฤติกรรมจะไม่ได้กำหนด
รหัสแก้ไขc
มากกว่าหนึ่งครั้งโดยไม่มีการแทรกแซงจุดลำดับและไม่มีการเข้าถึงเพื่อกำหนดค่าของวัตถุที่จัดเก็บ นี่คือการละเมิดที่ชัดเจนของข้อข้างต้นและด้วยเหตุนี้ผลที่ได้รับคำสั่งจากมาตรฐานที่มีพฤติกรรมที่ไม่ได้กำหนด[Ref 3]