โปรแกรมในระดับต่ำจำนวนมากใช้คำระเหยชนิดสำหรับการทำแผนที่หน่วยความจำและดังกล่าว แต่ฉันเรียงลำดับของการสับสนว่าสิ่งที่มันจริงๆจะอยู่ในพื้นหลัง กล่าวอีกนัยหนึ่งหมายความว่าอย่างไรเมื่อคอมไพเลอร์ไม่ "เพิ่มประสิทธิภาพ" ที่อยู่หน่วยความจำ
โปรแกรมในระดับต่ำจำนวนมากใช้คำระเหยชนิดสำหรับการทำแผนที่หน่วยความจำและดังกล่าว แต่ฉันเรียงลำดับของการสับสนว่าสิ่งที่มันจริงๆจะอยู่ในพื้นหลัง กล่าวอีกนัยหนึ่งหมายความว่าอย่างไรเมื่อคอมไพเลอร์ไม่ "เพิ่มประสิทธิภาพ" ที่อยู่หน่วยความจำ
คำตอบ:
volatile
หมายถึงโปรเซสเซอร์อื่นหรืออุปกรณ์ I / O หรือบางอย่างสามารถเปลี่ยนแปลงตัวแปรจากภายใต้คุณ
ด้วยตัวแปรธรรมดาขั้นตอนของโปรแกรมของคุณเป็นสิ่งเดียวที่จะเปลี่ยนแปลงได้ ตัวอย่างเช่นถ้าคุณอ่าน5
จากตัวแปรและคุณไม่เปลี่ยนมันจะยังคงมี5
อยู่ เนื่องจากคุณสามารถวางใจได้ว่าโปรแกรมของคุณไม่จำเป็นต้องใช้เวลาในการอ่านตัวแปรอีกครั้งในครั้งต่อไปที่คุณต้องการใช้ คอมไพเลอร์ C ++ นั้นฉลาดในการสร้างรหัสที่เพิ่งจำ5
ได้
แต่คุณสามารถอ่านมันเป็นแล้วบางทีข้อมูลระบบโหลดจากดิสก์ในหน่วยความจำที่เปลี่ยนไป5
500
หากคุณต้องการโปรแกรมของคุณในการอ่านค่าความสดใหม่ที่คุณต้องคอมไพเลอร์ที่จะไม่สมาร์ทมากเกินไปเกี่ยวกับการใช้ก่อนหน้านี้อ่าน500
5
คุณต้องบอกให้โหลดค่าใหม่ทุกครั้ง นั่นคือสิ่งที่volatile
ทำ
การเปรียบเทียบสำหรับเด็กอายุ 5 ปี
สมมติว่าคุณวางกระดาษแผ่นใหญ่ลงบนโต๊ะ ในมุมหนึ่งของกระดาษคุณเขียนคะแนนปัจจุบันของเกมต่อเนื่อง, 3 to 4
. จากนั้นคุณไปที่ด้านตรงข้ามของโต๊ะและเริ่มเขียนเรื่องราวเกี่ยวกับเกม เพื่อนของคุณที่กำลังดูเกมจะอัพเดตคะแนนในมุมนั้นเมื่อเกมดำเนินต่อไป เธอจะลบและเขียน3 to 4
3 to 5
เมื่อคุณใส่คะแนนเกมลงในเรื่องราวของคุณคุณสามารถ:
3 to 4
สมมติว่ามันไม่ได้เปลี่ยนอย่างสนุกสนาน (หรือไม่รังเกียจถ้าทำ) หรือ3 to 5
ตอนนี้) และเดินกลับ นั่นเป็นวิธีที่volatile
ตัวแปรทำหน้าที่volatile
หมายถึงสองสิ่ง:
ค่าของตัวแปรอาจเปลี่ยนแปลงได้โดยไม่ต้องมีรหัสของคุณเปลี่ยนแปลง ดังนั้นเมื่อใดก็ตามที่คอมไพเลอร์อ่านค่าของตัวแปรมันอาจไม่คิดว่ามันจะเหมือนกับครั้งสุดท้ายที่อ่านหรือว่าเป็นค่าเดียวกับค่าสุดท้ายที่เก็บไว้ แต่ต้องอ่านอีกครั้ง
การกระทำของการเก็บค่าตัวแปรแปรปรวนเป็น "ผลข้างเคียง" ซึ่งสามารถสังเกตได้จากภายนอกดังนั้นคอมไพเลอร์ไม่ได้รับอนุญาตให้ลบการกระทำของการเก็บค่า; ตัวอย่างเช่นหากเก็บสองค่าไว้ในแถวคอมไพเลอร์จะต้องเก็บค่าไว้สองครั้ง
ตัวอย่างเช่น:
i = 2;
i = i;
คอมไพเลอร์ต้องเก็บหมายเลขสองอ่านตัวแปร i เก็บตัวแปรที่อ่านเป็น i
มีสถานการณ์อื่น: หากฟังก์ชั่นใช้setjmp
และlongjmp
ถูกเรียกใช้ตัวแปรท้องถิ่นที่ระเหยได้ทั้งหมดของฟังก์ชั่นจะรับประกันว่าจะมีค่าสุดท้ายที่เก็บไว้ - นี่ไม่ใช่กรณีที่มีตัวแปรท้องถิ่นที่ไม่ลบเลือน
i
และความคุ้มค่าpi = &i
แล้วx = *pi
ไม่อ่านจากi
แต่อ่านที่ไม่ได้รับประกันว่าจะมีความหมายมีความผันผวน
i
มีการประกาศตามvolatile int i
นั้นpi
จะต้องมีการประกาศเป็นvolatile int *pi
ซึ่งในกรณีนี้*pi
คือการเข้าถึงที่ระเหยได้ไม่?
คำอธิบายบทคัดย่อ
ทั้ง C และ C ++ มีแนวคิดของเครื่องนามธรรม เมื่อรหัสใช้ค่าของตัวแปรบางตัวเครื่องนามธรรมบอกว่าการนำไปปฏิบัตินั้นต้องเข้าถึงค่าของตัวแปรนั้น รหัสของฟอร์มstatement_A; statement_B; statement_C;
จะต้องถูกดำเนินการตามลำดับที่ระบุ นิพจน์ทั่วไปของทั้งสามคำสั่งนั้นจะต้องคำนวณใหม่ทุกครั้งที่เกิดขึ้น
ต่อเครื่องที่เป็นนามธรรมให้ลำดับของงบstatement_A; statement_B; statement_C;
การดำเนินงานจะต้องดำเนินการstatement_A
อย่างครบถ้วนแล้วและในที่สุดก็statement_B
statement_C
การใช้งานไม่สามารถจำได้ว่าคุณกำหนดage
ค่าเป็น 5 ทุกคำสั่งที่อ้างอิงage
ต้องเข้าถึงค่าของตัวแปรนั้นแทน
จะไม่มีความจำเป็นสำหรับvolatile
คำหลักหากการใช้งานดำเนินการอย่างเคร่งครัดรหัส C หรือ C ++ ต่อข้อกำหนดนามธรรมเครื่อง เครื่องนามธรรม C และ C ++ ไม่มีแนวคิดของการลงทะเบียนไม่มีแนวคิดของนิพจน์ย่อยทั่วไปและลำดับการดำเนินการนั้นเข้มงวด
ทั้งสองภาษายังมีเป็นถ้ากฎ การนำไปใช้นั้นเป็นไปตามมาตรฐานตราบใดที่การใช้งานนั้นดำเนินการราวกับว่าได้ดำเนินการตามข้อกำหนดของเครื่องนามธรรม คอมไพเลอร์สามารถสันนิษฐานว่าตัวแปรที่ไม่ลบเลือนไม่ได้เปลี่ยนค่าระหว่างการมอบหมาย ตราบใดที่มันไม่ได้ทำลายas-if
กฎลำดับstatement_A; statement_B; statement_C;
อาจจะมีการดำเนินการโดยการดำเนินการเป็นส่วนหนึ่งของstatement_C
นั้นเป็นส่วนหนึ่งของstatement_A
แล้วทั้งหมดของstatement_B
แล้วส่วนที่เหลือของและสุดท้ายส่วนที่เหลือของstatement_A
statement_C
กฏas-ifเหล่านั้นใช้ไม่ได้กับvolatile
ตัวแปร ในแง่ของvolatile
ตัวแปรและฟังก์ชั่นการใช้งานจะต้องทำในสิ่งที่คุณบอกให้ทำและในลำดับที่คุณบอกให้ทำสิ่งต่าง ๆ
มีข้อเสียของสเปคเครื่องนามธรรม: มันช้า ข้อดีอย่างหนึ่งของ C และ C ++ เมื่อเปรียบเทียบกับภาษาอื่นคือมันค่อนข้างเร็ว กรณีนี้จะไม่เกิดขึ้นหากมีการเรียกใช้รหัสต่อเครื่องนามธรรมเหล่านี้ เป็นถ้ากฎนี้เป็นสิ่งที่ช่วยให้ C และ C ++ ที่จะให้ได้อย่างรวดเร็ว
คำตอบของ ELI5
หมายความว่าอย่างไรเมื่อคอมไพเลอร์ไม่ "เพิ่มประสิทธิภาพ" ที่อยู่หน่วยความจำ
ที่อยู่หน่วยความจำ "เพิ่มประสิทธิภาพ" เป็นแนวคิดขั้นสูงสิ่งที่ไม่ได้อยู่ในขอบเขตของความสามารถของเด็กอายุห้าปี เป็นไปตามมาตรฐานอายุห้าขวบจะทำในสิ่งที่คุณบอกให้ทำไม่มากไม่น้อย ด้วยvolatile
คุณกำลังบอกให้การใช้งานทำตัวเหมือนห้า: ไม่คิดไม่มีการปรับให้เหมาะสม แต่การใช้งานจะต้องทำในสิ่งที่รหัสบอกให้ทำ
(ไม่ใช่ -) สารระเหยเป็นคำแนะนำสำหรับคอมไพเลอร์วิธีการปรับโค้ดให้เหมาะสม (จากมุมมองการประกอบโค้ดโค้ดที่สร้างขึ้น):
คำตอบนั้นค่อนข้างคงเส้นคงวา แต่ขาดจุดสำคัญไป คุณกำลังบอกคอมไพเลอร์ว่าคุณต้องการจัดสรรพื้นที่และสำหรับทุกการเข้าถึงอ่านหรือเขียนคุณต้องการให้มันทำการเข้าถึงนั้น เราไม่ต้องการให้มันเพิ่มประสิทธิภาพการเข้าถึงเหล่านั้นหรือตัวแปรนั้นด้วยเหตุผลบางอย่าง
ใช่เหตุผลหนึ่งก็เพราะคนอื่นอาจเปลี่ยนคุณค่านั้นให้กับเรา อีกเหตุผลคือเราอาจเปลี่ยนค่านั้นให้กับคนอื่น คนอื่นไม่ว่าจะเป็นคนที่เปลี่ยนแปลงมันสำหรับเราหรือคนที่เรากำลังเปลี่ยนมันอาจจะเป็นฮาร์ดแวร์ / ตรรกะหรือซอฟต์แวร์ มักใช้เพื่อกำหนดการเข้าถึงการควบคุมและการลงทะเบียนสถานะในโปรแกรมฝังตัวโลหะเปลือยเขียนหรืออ่านจากฮาร์ดแวร์ ซอฟแวร์พูดคุยกับซอฟต์แวร์อธิบายในคำตอบอื่น ๆ
นอกจากนี้คุณยังจะเห็นความผันผวนที่ใช้ในการควบคุมเวลาและลำดับการเข้าถึงที่เกิดขึ้นหากคุณพยายามกำหนดเวลาส่วนของรหัสและคุณไม่ต้องใช้ตัวแปรผันแปรในคำถาม (เวลาเริ่มต้นเวลาสิ้นสุดและความแตกต่าง) จะต้องเป็น คำนวณได้ใกล้ถึงจุดสิ้นสุดคอมไพเลอร์มีอิสระในการเคลื่อนที่อย่างใดอย่างหนึ่งในการวัดเวลารอบ ๆ (ไม่ใช่ตำแหน่งที่เราวางไว้) ไม่ว่ามันจะไม่ระเหยง่าย แต่ประสบการณ์แสดงให้เห็นว่ามีโอกาสน้อยกว่า
ในบางครั้งคุณจะเห็นว่ามันใช้ในการเผาเพียงแค่เวลาไฟกระพริบนำระดับประถมซึ่งเป็นโลกแห่งโลหะเปลือยอาจใช้สารระเหยสำหรับตัวแปรที่นับเป็นจำนวนมากเพียงเพื่อเผาเวลาสำหรับสายตามนุษย์เพื่อมองนำ เปลี่ยนสถานะ ตัวอย่างขั้นสูงเพิ่มเติมจากนั้นใช้ตัวจับเวลาหรือเหตุการณ์อื่น ๆ เพื่อเบิร์นเวลา
volatile
ตัวแปรอายุและมันบอกว่า 5 และคุณอ่านมันอีกครั้งในปีหน้าคุณรับประกันว่าจะได้รับ 6