ก่อนที่คุณจะเริ่มตะโกนพฤติกรรมที่ไม่ได้กำหนดสิ่งนี้จะปรากฏในN4659 (C ++ 17) อย่างชัดเจน
i = i++ + 1; // the value of i is incremented
ยังอยู่ในN3337 (C ++ 11)
i = i++ + 1; // the behavior is undefined
มีอะไรเปลี่ยนแปลง
จากสิ่งที่ฉันสามารถรวบรวมได้จาก[N4659 basic.exec]
ยกเว้นที่ระบุไว้การประเมินผลของตัวถูกดำเนินการของแต่ละตัวดำเนินการและ subexpressions ของแต่ละนิพจน์จะไม่เกิดขึ้น [... ] การคำนวณค่าของตัวถูกดำเนินการของผู้ประกอบการจะถูกจัดลำดับก่อนที่การคำนวณมูลค่าของผลลัพธ์ของผู้ประกอบการ หากผลข้างเคียงต่อตำแหน่งหน่วยความจำนั้นไม่สัมพันธ์กันกับผลข้างเคียงอื่นในตำแหน่งหน่วยความจำเดียวกันหรือการคำนวณค่าโดยใช้ค่าของวัตถุใด ๆ ในตำแหน่งหน่วยความจำเดียวกันและอาจไม่เกิดขึ้นพร้อมกันพฤติกรรมจะไม่ถูกกำหนด
ตำแหน่งที่กำหนดค่าไว้ที่[N4659 basic.type]
สำหรับประเภทที่คัดลอกได้เล็กน้อยการแทนค่าเป็นชุดของบิตในการแสดงวัตถุที่กำหนดค่าซึ่งเป็นองค์ประกอบที่แยกจากกันหนึ่งชุดของการกำหนดค่าการนำไปปฏิบัติ
ยกเว้นที่ระบุไว้การประเมินผลของตัวถูกดำเนินการของแต่ละตัวดำเนินการและ subexpressions ของแต่ละนิพจน์จะไม่เกิดขึ้น [... ] การคำนวณค่าของตัวถูกดำเนินการของผู้ประกอบการจะถูกจัดลำดับก่อนที่การคำนวณมูลค่าของผลลัพธ์ของผู้ประกอบการ หากผลข้างเคียงของวัตถุสเกลาร์นั้นสัมพันธ์กันกับผลข้างเคียงอื่นในวัตถุสเกลาร์เดียวกันหรือการคำนวณค่าโดยใช้ค่าของวัตถุสเกลาร์เดียวกันพฤติกรรมจะไม่ได้กำหนดไว้
เช่นเดียวกันค่าจะถูกกำหนดที่[N3337 basic.type]
สำหรับประเภทที่คัดลอกได้เล็กน้อยการแทนค่าเป็นชุดของบิตในการแสดงวัตถุที่กำหนดค่าซึ่งเป็นองค์ประกอบที่ไม่ต่อเนื่องของชุดค่าที่นำไปปฏิบัติ
พวกเขาเป็นเหมือนกันยกเว้นการกล่าวถึงเห็นพ้องด้วยซึ่งไม่สำคัญและมีการใช้งานของหน่วยความจำตำแหน่งแทนวัตถุเกลาที่
ประเภทเลขคณิตประเภทการนับประเภทตัวชี้ตัวชี้ไปยังประเภทสมาชิก
std::nullptr_t
และรุ่นที่ผ่านการรับรอง cv ของประเภทเหล่านี้เรียกรวมกันว่าประเภทสเกลาร์
ซึ่งไม่ส่งผลกระทบต่อตัวอย่าง
ผู้ประกอบการที่ได้รับมอบหมาย (=) และผู้ประกอบการที่ได้รับมอบหมายสารกลุ่มทั้งหมดจากขวาไปซ้าย ทั้งหมดต้องการ lvalue ที่ปรับเปลี่ยนได้เป็นตัวถูกดำเนินการด้านซ้ายและส่งคืน lvalue ที่อ้างถึงตัวถูกดำเนินการด้านซ้าย ผลลัพธ์ในทุกกรณีเป็นบิตฟิลด์หากตัวถูกดำเนินการด้านซ้ายเป็นบิตฟิลด์ ในทุกกรณีการมอบหมายนั้นจะถูกจัดลำดับหลังจากการคำนวณค่าของตัวถูกดำเนินการด้านขวาและซ้ายและก่อนการคำนวณมูลค่าของนิพจน์การมอบหมาย ตัวถูกดำเนินการด้านขวาถูกจัดลำดับก่อนหน้าตัวถูกดำเนินการด้านซ้าย
ผู้ประกอบการที่ได้รับมอบหมาย (=) และผู้ประกอบการที่ได้รับมอบหมายสารกลุ่มทั้งหมดจากขวาไปซ้าย ทั้งหมดต้องการ lvalue ที่ปรับเปลี่ยนได้เป็นตัวถูกดำเนินการด้านซ้ายและส่งคืน lvalue ที่อ้างถึงตัวถูกดำเนินการด้านซ้าย ผลลัพธ์ในทุกกรณีเป็นบิตฟิลด์หากตัวถูกดำเนินการด้านซ้ายเป็นบิตฟิลด์ ในทุกกรณีการมอบหมายนั้นจะถูกจัดลำดับหลังจากการคำนวณค่าของตัวถูกดำเนินการด้านขวาและซ้ายและก่อนการคำนวณมูลค่าของนิพจน์การมอบหมาย
ความแตกต่างเพียงอย่างเดียวคือประโยคสุดท้ายที่หายไปใน N3337
ประโยคสุดท้ายไม่ควรมีความสำคัญใด ๆ เนื่องจากตัวถูกดำเนินการด้านซ้ายi
ไม่ใช่"ผลข้างเคียงอื่น"หรือ"การใช้ค่าของวัตถุสเกลาร์เดียวกัน"เนื่องจากการแสดงออกของidเป็นค่า lvalue
i = i++ + 1;
เมื่อต้องเผชิญกับรหัสเช่น