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