คอมไพเลอร์ได้รับอนุญาตให้ระเหยสารในท้องถิ่นได้หรือไม่?
พิจารณารหัสง่าย ๆ นี้: void g(); void foo() { volatile bool x = false; if (x) g(); } https://godbolt.org/z/I2kBY7 คุณจะเห็นว่าค่าgccมิได้เพิ่มประสิทธิภาพการโทรมีศักยภาพในการclang gสิ่งนี้ถูกต้องในความเข้าใจของฉัน: เครื่องนามธรรมคือการสันนิษฐานว่าvolatileตัวแปรอาจเปลี่ยนแปลงได้ตลอดเวลา (เนื่องจากเป็นเช่นการแมปฮาร์ดแวร์) ดังนั้นการfalseเริ่มต้นการพับการifตรวจสอบอย่างต่อเนื่องจะผิด แต่ MSVC กำจัดการเรียกไปที่gทั้งหมด (ทำให้การอ่านและเขียนไปยังvolatileแม้ว่า!) พฤติกรรมนี้เป็นไปตามมาตรฐานหรือไม่ พื้นหลัง: ฉันใช้โครงสร้างชนิดนี้เป็นครั้งคราวเพื่อให้สามารถเปิด / ปิดการดีบักเอาต์พุตแบบทันที: คอมไพเลอร์ต้องอ่านค่าจากหน่วยความจำเสมอดังนั้นการเปลี่ยนตัวแปร / หน่วยความจำในระหว่างการดีบักควรปรับเปลี่ยนการควบคุมตามลำดับ . เอาท์พุท MSVC จะอ่านค่าใหม่ แต่ไม่สนใจมัน (น่าจะเป็นเพราะการพับและ / หรือการกำจัดรหัสที่ตายแล้ว) ซึ่งแน่นอนว่าเอาชนะความตั้งใจของฉันที่นี่ การแก้ไข: การกำจัดของการอ่านและการเขียนvolatileถูกกล่าวถึงที่นี่: มันอนุญาตให้คอมไพเลอร์เพื่อปรับให้เหมาะสมกับตัวแปรที่ระเหยได้หรือไม่? (ขอบคุณนาธาน!) ฉันคิดว่ามาตรฐานมีความชัดเจนอย่างมากที่ผู้อ่านและเขียนจะต้องเกิดขึ้น แต่การสนทนานั้นไม่ครอบคลุมว่าจะเป็นการถูกกฎหมายหรือไม่ที่คอมไพเลอร์จะใช้ผลลัพธ์ของการอ่านเพื่อการอนุญาตและการปรับให้เหมาะสมตามนั้น …