“ IB” และ“ UB” หมายความว่าอย่างไร


111

ฉันเคยเห็นคำว่า "IB" และ "UB" ใช้หลายครั้งโดยเฉพาะในบริบทของ C ++ ฉันได้ลองใช้ googling แล้ว แต่เห็นได้ชัดว่าชุดค่าผสมสองตัวอักษรเหล่านี้มีประโยชน์มาก : ป

ฉันถามคุณว่า ... พวกเขาหมายความว่าอย่างไรเมื่อพวกเขาพูดราวกับว่าพวกเขาเป็นสิ่งที่ไม่ดี?


5
หากคุณตัดสินใจที่จะย้อนการแก้ไขของผู้อื่นโปรดตรวจสอบให้แน่ใจว่าการสะกดเครื่องหมายวรรคตอนและไวยากรณ์ของคุณสมบูรณ์แบบ การย้อนกลับการแก้ไขซึ่งเป็นการปรับปรุงที่สำคัญกว่าข้อความต้นฉบับนั้นไม่มีจุดหมาย
Robert Harvey

คำตอบ:


140

IB: พฤติกรรมที่กำหนดการนำไปใช้งาน มาตรฐานปล่อยให้คอมไพเลอร์ / แพลตฟอร์มเฉพาะกำหนดลักษณะการทำงานที่แม่นยำ แต่ต้องการให้กำหนด

การใช้พฤติกรรมที่กำหนดโดยการนำไปใช้จะมีประโยชน์ แต่ทำให้โค้ดของคุณพกพาได้น้อยลง

UB: พฤติกรรมที่ไม่ได้กำหนด มาตรฐานไม่ได้ระบุว่าโปรแกรมที่เรียกใช้พฤติกรรมที่ไม่ได้กำหนดควรทำงานอย่างไร มีชื่อเรียกอีกอย่างว่า "จมูกปีศาจ" เพราะตามหลักวิชาแล้วมันสามารถทำให้ปีศาจบินออกจากจมูกของคุณได้

การใช้พฤติกรรมที่ไม่ได้กำหนดมักเป็นความคิดที่ไม่ดี แม้ว่าจะดูเหมือนว่าจะใช้งานได้ในบางครั้งการเปลี่ยนแปลงสภาพแวดล้อมคอมไพเลอร์หรือแพลตฟอร์มใด ๆ ก็สามารถทำลายโค้ดของคุณได้แบบสุ่ม


11
ฉันยังคงรอปีศาจที่บินออกจากจมูกของใครบางคนเนื่องจากการใช้พฤติกรรมที่ไม่ได้กำหนดใน C ++ ฉันเดาว่ามันจะเกิดขึ้นเมื่อคอมไพเลอร์ตัวแรกปฏิบัติตามมาตรฐาน C ++ ใหม่อย่างสมบูรณ์
OregonGhost

4
@OregonGhost: ฉันเดาว่าคุณพูดถูก ฉันเคยเห็นมันเกิดขึ้นกับยูนิคอร์นสองสามครั้ง แต่ไม่เคยเป็นปีศาจ
โธมัส

33
@OregonGhost - มาตรฐานไม่ได้ระบุจำนวนเขาที่ปีศาจควรมี
DVK

5
@ Michael Burr: ฉันชอบ "ติดไฟ" มากกว่า เห็นได้ชัดว่าเป็นภัยพิบัติและอย่างน้อยก็มีความน่าเชื่อถือที่คลุมเครือ (บางครั้งฮาร์ดแวร์คอมพิวเตอร์ก็ลุกเป็นไฟโดยยอมรับว่าเป็นสาเหตุของฮาร์ดแวร์มากกว่าความล้มเหลวของซอฟต์แวร์ในกรณีของระบบใด ๆ ที่คุณกำลังอ่านหัวข้อนี้)
Steve Jessop

1
เป็นเรื่องตลกที่ไม่มีใครตอบคำถามนี้มีชื่อเสียงน้อยกว่า 30k

19

พฤติกรรมที่กำหนดการนำไปใช้และพฤติกรรมที่ไม่ได้กำหนด

มาตรฐาน C ++ มีความเฉพาะเจาะจงมากเกี่ยวกับผลกระทบของโครงสร้างต่างๆและโดยเฉพาะอย่างยิ่งคุณควรตระหนักถึงปัญหาเหล่านี้อยู่เสมอ:

  • พฤติกรรมที่ไม่ได้กำหนดหมายความว่าไม่มีการรับประกันใด ๆ รหัสสามารถทำงานหรือมันอาจจะจุดไฟเผา harddrive ของคุณหรือปีศาจให้บินออกจากจมูกของคุณ สำหรับภาษา C ++ อาจมีอะไรเกิดขึ้นอย่างแน่นอน ในทางปฏิบัติโดยทั่วไปหมายความว่าคุณมีข้อบกพร่องที่ไม่สามารถกู้คืนได้ หากเกิดเหตุการณ์นี้ขึ้นคุณจะไม่สามารถวางใจอะไรเกี่ยวกับแอปพลิเคชันของคุณได้เลย(เนื่องจากผลกระทบอย่างหนึ่งของพฤติกรรมที่ไม่ได้กำหนดนี้อาจทำให้หน่วยความจำที่เหลือใช้แอปของคุณเสียหาย) ไม่จำเป็นต้องสอดคล้องกันดังนั้นการรันโปรแกรมสองครั้งอาจให้ผลลัพธ์ที่แตกต่างกัน อาจขึ้นอยู่กับระยะของดวงจันทร์สีของเสื้อที่คุณสวมใส่หรืออย่างอื่น

  • พฤติกรรมที่ไม่ระบุหมายความว่าโปรแกรมต้องทำสิ่งที่ดีและสม่ำเสมอ แต่ไม่จำเป็นต้องจัดทำเอกสารนี้

  • พฤติกรรมที่กำหนดในการนำไปใช้นั้นคล้ายกับไม่ระบุ แต่ผู้เขียนคอมไพเลอร์ต้องจัดทำเป็นเอกสารด้วย ตัวอย่างนี้เป็นผลมาจากไฟล์reinterpret_cast. โดยปกติแล้วมันจะเปลี่ยนชนิดของตัวชี้โดยไม่ต้องแก้ไขที่อยู่ แต่จริงๆแล้วการทำแผนที่นั้นถูกกำหนดให้ใช้งานได้ดังนั้นคอมไพเลอร์สามารถแมปไปยังที่อยู่ที่แตกต่างกันโดยสิ้นเชิงตราบเท่าที่มีการบันทึกตัวเลือกนี้ไว้ อีกตัวอย่างหนึ่งคือขนาดของ int มาตรฐาน C ++ ไม่สนใจว่าจะเป็น 2, 4 หรือ 8 ไบต์ แต่คอมไพเลอร์จะต้องจัดทำเป็นเอกสาร

แต่ที่พบบ่อยสำหรับสิ่งเหล่านี้คือหลีกเลี่ยงได้ดีที่สุด หากเป็นไปได้ให้ยึดติดกับพฤติกรรมที่กำหนดไว้ 100% โดยมาตรฐาน C ++ เอง ด้วยวิธีนี้คุณจึงรับประกันการพกพา

คุณมักจะต้องพึ่งพาพฤติกรรมที่กำหนดโดยการนำไปใช้งานบางอย่างเช่นกัน อาจเป็นสิ่งที่หลีกเลี่ยงไม่ได้ แต่คุณควรใส่ใจกับมันและระวังว่าคุณกำลังอาศัยบางสิ่งที่อาจเปลี่ยนแปลงไประหว่างคอมไพเลอร์ต่างๆ

ในทางกลับกันควรหลีกเลี่ยงพฤติกรรมที่ไม่ได้กำหนดไว้เสมอ โดยทั่วไปคุณควรสมมติว่ามันทำให้โปรแกรมของคุณระเบิดไม่ทางใดก็ทางหนึ่ง


1
UB ควรหลีกเลี่ยงถ้าคุณดูแลเกี่ยวกับการพกพา การนำไปใช้งานเฉพาะสามารถกำหนดสิ่งที่เกิดขึ้นสำหรับพฤติกรรมที่ไม่ได้กำหนดไว้และในบางกรณี (โดยเฉพาะไดรเวอร์อุปกรณ์และระบบฝังตัวขนาดเล็ก) คุณจำเป็นต้องใช้สิ่งเหล่านั้น
Jerry Coffin

3
@Jerry: ไม่มี UB ควรหลีกเลี่ยงถ้ามันจะไม่ได้กำหนดอย่างสิ้นเชิง หากแพลตฟอร์ม / การนำไปใช้ / รันไทม์ / คอมไพเลอร์ให้การรับประกันเพิ่มเติมคุณสามารถพึ่งพาพฤติกรรมและสูญเสียความสามารถในการพกพา แต่แล้วก็ไม่ได้กำหนดไว้อย่างชัดเจนอีกต่อไป ... แม้ว่าส่วนใหญ่แล้วคุณจะไม่มีการค้ำประกันดังกล่าวและไม่ได้กำหนดก็ไม่ได้กำหนดไว้เท่านั้นและควรหลีกเลี่ยงค่าใช้จ่ายทั้งหมด
ม.ค.

"สอดคล้องกัน" อาจเป็นคำอธิบายพฤติกรรมที่ไม่ระบุรายละเอียดที่ทำให้เข้าใจผิด มันจะต้องมีความสอดคล้องกับบริบททั่วไปของการดำเนินการเช่นถ้ามีการแสดงออก "ค่าที่ไม่ได้ระบุ" แล้วผลจะต้องเป็นค่าถ้าคุณเก็บไว้แล้วค่าที่เก็บไว้หลังจากนั้นจะต้องเปรียบเทียบเท่ากับตัวเองและอื่น ๆ แต่ผลลัพธ์ที่ไม่ระบุไม่จำเป็นต้องสอดคล้องกันเมื่อเวลาผ่านไป (เอาต์พุตเดียวกันสำหรับอินพุตเดียวกันหากคุณเรียกใช้อีกครั้ง) หรือแม้กระทั่งดีเทอร์มินิสติก
Steve Jessop

"ไม่ระบุอีกต่อไป" - เป็นไปตามมาตรฐานที่ไม่ได้กำหนดไว้ทั้งหมดและ UB เป็นความหมายสั้น ๆ ที่ไม่ได้กำหนดโดยมาตรฐาน ในตัวอย่างของคุณถูกกำหนดโดยการใช้งาน สำหรับเรื่องนั้นคุณสามารถพึ่งพาพฤติกรรมที่ไม่ได้กำหนดโดยมาตรฐานหรือการใช้งานหากคุณตรวจสอบรหัสวัตถุแล้วและไม่ได้วางแผนที่จะคอมไพล์ซ้ำอีกครั้ง ;-)
Steve Jessop

"หลังจากนั้นจะต้องเปรียบเทียบเท่ากับตัวมันเอง" อืมเว้นแต่จะเป็น NaN อย่างไรก็ตามมันจะต้องมีพฤติกรรมที่จำเป็นสำหรับประเภทของมัน
Steve Jessop

8
  • IB: เป็นพฤติกรรมที่กำหนดการนำไปใช้ - คอมไพเลอร์ต้องบันทึกสิ่งที่ทำ การ>>ดำเนินการกับค่าลบเป็นตัวอย่าง

  • UB: พฤติกรรมที่ไม่ได้กำหนด - คอมไพเลอร์สามารถทำสิ่งที่เคยได้รวมถึงการหยุดทำงานหรือให้ผลลัพธ์ที่คาดเดาไม่ได้ การอ้างถึงตัวชี้ค่าว่างจะอยู่ในหมวดหมู่นี้ แต่ยังรวมถึงสิ่งที่เป็นตัวย่อยเช่นเลขคณิตของตัวชี้ที่อยู่นอกขอบเขตของวัตถุอาร์เรย์

คำที่เกี่ยวข้องอีกคำคือ "พฤติกรรมที่ไม่ระบุ" นี่เป็นประเภทระหว่างพฤติกรรมที่กำหนดและไม่ได้กำหนดการนำไปใช้งาน สำหรับพฤติกรรมที่ไม่ระบุรายละเอียดคอมไพลเลอร์ต้องทำบางอย่างตามมาตรฐาน แต่ตัวเลือกใดที่มาตรฐานกำหนดนั้นขึ้นอยู่กับคอมไพเลอร์และไม่จำเป็นต้องกำหนด (หรือสอดคล้องกัน) สิ่งต่างๆเช่นลำดับการประเมินนิพจน์ย่อยจัดอยู่ในหมวดหมู่นี้ คอมไพเลอร์สามารถดำเนินการเหล่านี้ตามลำดับที่ต้องการและสามารถทำได้แตกต่างกันในบิลด์ที่แตกต่างกันหรือแม้กระทั่งในการรันที่แตกต่างกันของบิลด์เดียวกัน (ไม่น่าจะเป็นไปได้ แต่ได้รับอนุญาต)


4

เวอร์ชันสั้น:

พฤติกรรมที่กำหนดการนำไปใช้งาน (IB):โปรแกรมถูกต้อง แต่ไม่แน่นอน *

พฤติกรรมที่ไม่ได้กำหนด (UB):โปรแกรมไม่ถูกต้อง (เช่นบั๊ก !)

*) "ไม่แน่นอน" เท่าที่เกี่ยวข้องกับมาตรฐานภาษาแน่นอนว่ามันจะถูกกำหนดบนแพลตฟอร์มใด ๆ ที่ตายตัว


หากมาตรฐานระบุว่าการดำเนินการเรียกใช้พฤติกรรมที่กำหนดการนำไปใช้งานจำเป็นต้องระบุพฤติกรรมที่สอดคล้องกันซึ่งเป็นผลมาจากการกระทำนั้น น่าเสียดายที่ไม่มีประเภทของพฤติกรรมที่จะต้องนำไปใช้เพื่อระบุผลที่เป็นไปได้ แต่ไม่จำเป็นต้องให้ผลลัพธ์ใด ๆ เกิดขึ้นอย่างสม่ำเสมอ
supercat

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.