ฉันเคยเห็นคำว่า "IB" และ "UB" ใช้หลายครั้งโดยเฉพาะในบริบทของ C ++ ฉันได้ลองใช้ googling แล้ว แต่เห็นได้ชัดว่าชุดค่าผสมสองตัวอักษรเหล่านี้มีประโยชน์มาก : ป
ฉันถามคุณว่า ... พวกเขาหมายความว่าอย่างไรเมื่อพวกเขาพูดราวกับว่าพวกเขาเป็นสิ่งที่ไม่ดี?
ฉันเคยเห็นคำว่า "IB" และ "UB" ใช้หลายครั้งโดยเฉพาะในบริบทของ C ++ ฉันได้ลองใช้ googling แล้ว แต่เห็นได้ชัดว่าชุดค่าผสมสองตัวอักษรเหล่านี้มีประโยชน์มาก : ป
ฉันถามคุณว่า ... พวกเขาหมายความว่าอย่างไรเมื่อพวกเขาพูดราวกับว่าพวกเขาเป็นสิ่งที่ไม่ดี?
คำตอบ:
IB: พฤติกรรมที่กำหนดการนำไปใช้งาน มาตรฐานปล่อยให้คอมไพเลอร์ / แพลตฟอร์มเฉพาะกำหนดลักษณะการทำงานที่แม่นยำ แต่ต้องการให้กำหนด
การใช้พฤติกรรมที่กำหนดโดยการนำไปใช้จะมีประโยชน์ แต่ทำให้โค้ดของคุณพกพาได้น้อยลง
UB: พฤติกรรมที่ไม่ได้กำหนด มาตรฐานไม่ได้ระบุว่าโปรแกรมที่เรียกใช้พฤติกรรมที่ไม่ได้กำหนดควรทำงานอย่างไร มีชื่อเรียกอีกอย่างว่า "จมูกปีศาจ" เพราะตามหลักวิชาแล้วมันสามารถทำให้ปีศาจบินออกจากจมูกของคุณได้
การใช้พฤติกรรมที่ไม่ได้กำหนดมักเป็นความคิดที่ไม่ดี แม้ว่าจะดูเหมือนว่าจะใช้งานได้ในบางครั้งการเปลี่ยนแปลงสภาพแวดล้อมคอมไพเลอร์หรือแพลตฟอร์มใด ๆ ก็สามารถทำลายโค้ดของคุณได้แบบสุ่ม
พฤติกรรมที่กำหนดการนำไปใช้และพฤติกรรมที่ไม่ได้กำหนด
มาตรฐาน C ++ มีความเฉพาะเจาะจงมากเกี่ยวกับผลกระทบของโครงสร้างต่างๆและโดยเฉพาะอย่างยิ่งคุณควรตระหนักถึงปัญหาเหล่านี้อยู่เสมอ:
พฤติกรรมที่ไม่ได้กำหนดหมายความว่าไม่มีการรับประกันใด ๆ รหัสสามารถทำงานหรือมันอาจจะจุดไฟเผา harddrive ของคุณหรือปีศาจให้บินออกจากจมูกของคุณ สำหรับภาษา C ++ อาจมีอะไรเกิดขึ้นอย่างแน่นอน ในทางปฏิบัติโดยทั่วไปหมายความว่าคุณมีข้อบกพร่องที่ไม่สามารถกู้คืนได้ หากเกิดเหตุการณ์นี้ขึ้นคุณจะไม่สามารถวางใจอะไรเกี่ยวกับแอปพลิเคชันของคุณได้เลย(เนื่องจากผลกระทบอย่างหนึ่งของพฤติกรรมที่ไม่ได้กำหนดนี้อาจทำให้หน่วยความจำที่เหลือใช้แอปของคุณเสียหาย) ไม่จำเป็นต้องสอดคล้องกันดังนั้นการรันโปรแกรมสองครั้งอาจให้ผลลัพธ์ที่แตกต่างกัน อาจขึ้นอยู่กับระยะของดวงจันทร์สีของเสื้อที่คุณสวมใส่หรืออย่างอื่น
พฤติกรรมที่ไม่ระบุหมายความว่าโปรแกรมต้องทำสิ่งที่ดีและสม่ำเสมอ แต่ไม่จำเป็นต้องจัดทำเอกสารนี้
พฤติกรรมที่กำหนดในการนำไปใช้นั้นคล้ายกับไม่ระบุ แต่ผู้เขียนคอมไพเลอร์ต้องจัดทำเป็นเอกสารด้วย ตัวอย่างนี้เป็นผลมาจากไฟล์reinterpret_cast
. โดยปกติแล้วมันจะเปลี่ยนชนิดของตัวชี้โดยไม่ต้องแก้ไขที่อยู่ แต่จริงๆแล้วการทำแผนที่นั้นถูกกำหนดให้ใช้งานได้ดังนั้นคอมไพเลอร์สามารถแมปไปยังที่อยู่ที่แตกต่างกันโดยสิ้นเชิงตราบเท่าที่มีการบันทึกตัวเลือกนี้ไว้ อีกตัวอย่างหนึ่งคือขนาดของ int มาตรฐาน C ++ ไม่สนใจว่าจะเป็น 2, 4 หรือ 8 ไบต์ แต่คอมไพเลอร์จะต้องจัดทำเป็นเอกสาร
แต่ที่พบบ่อยสำหรับสิ่งเหล่านี้คือหลีกเลี่ยงได้ดีที่สุด หากเป็นไปได้ให้ยึดติดกับพฤติกรรมที่กำหนดไว้ 100% โดยมาตรฐาน C ++ เอง ด้วยวิธีนี้คุณจึงรับประกันการพกพา
คุณมักจะต้องพึ่งพาพฤติกรรมที่กำหนดโดยการนำไปใช้งานบางอย่างเช่นกัน อาจเป็นสิ่งที่หลีกเลี่ยงไม่ได้ แต่คุณควรใส่ใจกับมันและระวังว่าคุณกำลังอาศัยบางสิ่งที่อาจเปลี่ยนแปลงไประหว่างคอมไพเลอร์ต่างๆ
ในทางกลับกันควรหลีกเลี่ยงพฤติกรรมที่ไม่ได้กำหนดไว้เสมอ โดยทั่วไปคุณควรสมมติว่ามันทำให้โปรแกรมของคุณระเบิดไม่ทางใดก็ทางหนึ่ง
IB: เป็นพฤติกรรมที่กำหนดการนำไปใช้ - คอมไพเลอร์ต้องบันทึกสิ่งที่ทำ การ>>
ดำเนินการกับค่าลบเป็นตัวอย่าง
UB: พฤติกรรมที่ไม่ได้กำหนด - คอมไพเลอร์สามารถทำสิ่งที่เคยได้รวมถึงการหยุดทำงานหรือให้ผลลัพธ์ที่คาดเดาไม่ได้ การอ้างถึงตัวชี้ค่าว่างจะอยู่ในหมวดหมู่นี้ แต่ยังรวมถึงสิ่งที่เป็นตัวย่อยเช่นเลขคณิตของตัวชี้ที่อยู่นอกขอบเขตของวัตถุอาร์เรย์
คำที่เกี่ยวข้องอีกคำคือ "พฤติกรรมที่ไม่ระบุ" นี่เป็นประเภทระหว่างพฤติกรรมที่กำหนดและไม่ได้กำหนดการนำไปใช้งาน สำหรับพฤติกรรมที่ไม่ระบุรายละเอียดคอมไพลเลอร์ต้องทำบางอย่างตามมาตรฐาน แต่ตัวเลือกใดที่มาตรฐานกำหนดนั้นขึ้นอยู่กับคอมไพเลอร์และไม่จำเป็นต้องกำหนด (หรือสอดคล้องกัน) สิ่งต่างๆเช่นลำดับการประเมินนิพจน์ย่อยจัดอยู่ในหมวดหมู่นี้ คอมไพเลอร์สามารถดำเนินการเหล่านี้ตามลำดับที่ต้องการและสามารถทำได้แตกต่างกันในบิลด์ที่แตกต่างกันหรือแม้กระทั่งในการรันที่แตกต่างกันของบิลด์เดียวกัน (ไม่น่าจะเป็นไปได้ แต่ได้รับอนุญาต)
เวอร์ชันสั้น:
พฤติกรรมที่กำหนดการนำไปใช้งาน (IB):โปรแกรมถูกต้อง แต่ไม่แน่นอน *
พฤติกรรมที่ไม่ได้กำหนด (UB):โปรแกรมไม่ถูกต้อง (เช่นบั๊ก !)
*) "ไม่แน่นอน" เท่าที่เกี่ยวข้องกับมาตรฐานภาษาแน่นอนว่ามันจะถูกกำหนดบนแพลตฟอร์มใด ๆ ที่ตายตัว