กลับไปหน้าบทความ

อ่าน 2 นาที

ความปลอดภัยที่เป็นข้อยกเว้น

ความปลอดภัยของข้อยกเว้นคือสถานะของโค้ดที่ทำงานได้อย่างถูกต้องเมื่อมีการโยนข้อยกเว้นเพื่อช่วยให้มั่นใจในความปลอดภัยของข้อยกเว้น นักพัฒนาไลบรารีมาตรฐาน...

ความปลอดภัยที่เป็นข้อยกเว้น

ความปลอดภัยของข้อยกเว้นคือสถานะของโค้ดที่ทำงานได้อย่างถูกต้องเมื่อมีการโยนข้อยกเว้น[ 1 ]เพื่อช่วยให้มั่นใจในความปลอดภัยของข้อยกเว้น นักพัฒนาไลบรารีมาตรฐาน C++ได้คิดค้นชุดระดับความปลอดภัยของข้อยกเว้น ซึ่งเป็นการรับประกันตามสัญญาเกี่ยวกับพฤติกรรมของการดำเนินการของโครงสร้างข้อมูลที่เกี่ยวข้องกับข้อยกเว้น ผู้พัฒนาไลบรารีและลูกค้าสามารถใช้การรับประกันเหล่านี้เมื่อพิจารณาถึง ความถูกต้อง ของการจัดการข้อยกเว้นระดับความปลอดภัยของข้อยกเว้นใช้ได้กับภาษาอื่นๆ และกลไกการจัดการข้อผิดพลาดเช่นกัน[ 2 ]

ประวัติศาสตร์

ดังที่David Abrahamsเขียนไว้ว่า "ไม่มีใครเคยพูดถึง 'ความปลอดภัยจากข้อผิดพลาด' มาก่อนที่ C++ จะมีข้อยกเว้น" [ 3 ] คำนี้ปรากฏเป็นหัวข้อของเอกสารเผยแพร่ในJTC1/SC22/WG21ซึ่งเป็นคณะกรรมการมาตรฐาน C++ ตั้งแต่ปี 1994 [ 4 ]ความปลอดภัยของข้อยกเว้นสำหรับไลบรารีมาตรฐาน C++ ได้รับการกำหนดอย่างเป็นทางการครั้งแรกสำหรับSTLportโดย Abrahams ซึ่งได้กำหนดความแตกต่างระหว่างความปลอดภัยพื้นฐานและความปลอดภัยที่เข้มงวด[ 5 ]สิ่งนี้ได้รับการขยายไปสู่การรับประกันพื้นฐาน/เข้มงวด/ไม่โยนข้อยกเว้นที่ทันสมัยในข้อเสนอในภายหลัง[ 6 ]

พื้นหลัง

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

  1. ขั้นตอนหนึ่งของการดำเนินการกับโครงสร้างข้อมูลที่เปลี่ยนแปลงได้จะแก้ไขข้อมูลและทำลายคุณสมบัติคงที่ของข้อมูล
  2. เกิดข้อผิดพลาดขึ้น และการควบคุมจะ "ส่งต่อไปยังระดับที่สูงขึ้น" โดยข้ามส่วนที่เหลือของโค้ดการทำงานที่ทำหน้าที่คืนค่าสถานะคงที่
  3. ข้อผิดพลาดถูกตรวจจับและกู้คืน หรือfinallyมีการเข้าสู่บล็อก
  4. โครงสร้างข้อมูลที่มีเงื่อนไขคงที่ที่เสียหายถูกนำไปใช้โดยโค้ดที่ถือว่าเงื่อนไขคงที่นั้นถูกต้อง ส่งผลให้เกิดข้อผิดพลาด

โค้ดที่มีบั๊กดังที่กล่าวมาข้างต้นอาจกล่าวได้ว่า "ไม่ปลอดภัยต่อข้อยกเว้น" [ 7 ]

การจำแนกประเภท

ไลบรารีมาตรฐาน C++มีระดับความปลอดภัยของข้อยกเว้นหลายระดับ (เรียงลำดับจากความปลอดภัยมากที่สุดไปน้อยที่สุด): [ 8 ]

  1. รับประกันความสำเร็จโดยไม่ผิดพลาดหรือที่เรียกว่าความโปร่งใสของความล้มเหลว : การดำเนินงานได้รับการรับประกันว่าจะประสบความสำเร็จและตรงตามข้อกำหนดทั้งหมด แม้ในสถานการณ์พิเศษ หากเกิดข้อผิดพลาดขึ้น จะได้รับการจัดการภายในและลูกค้าจะไม่พบเห็น
  2. ความปลอดภัยของข้อยกเว้นที่แข็งแกร่งหรือที่รู้จักกันในชื่อความหมายของการยืนยันหรือการยกเลิก : การดำเนินการอาจล้มเหลว แต่การดำเนินการที่ล้มเหลวรับประกันว่าจะไม่มีผลข้างเคียง ทำให้ค่าเดิมยังคงอยู่[ 9 ]
  3. ความปลอดภัยของข้อยกเว้นขั้นพื้นฐาน : การดำเนินการบางส่วนของกระบวนการที่ล้มเหลวอาจส่งผลให้เกิดผลข้างเคียง แต่เงื่อนไขพื้นฐาน ทั้งหมด จะยังคงอยู่ ข้อมูลที่จัดเก็บไว้จะมีค่าที่ถูกต้อง ซึ่งอาจแตกต่างจากค่าเดิมการรั่วไหลของทรัพยากร (รวมถึงการรั่วไหลของหน่วยความจำ ) มักจะถูกตัดออกไปโดยเงื่อนไขพื้นฐานที่ระบุว่าทรัพยากรทั้งหมดได้รับการตรวจสอบและจัดการแล้ว
  4. ไม่มีข้อยกเว้นด้านความปลอดภัย : ไม่มีการรับประกันใดๆ ทั้งสิ้น

โดยทั่วไปแล้ว การเขียนโค้ดที่แข็งแกร่งนั้นจำเป็นต้องมีระบบรักษาความปลอดภัยจากข้อยกเว้นขั้นพื้นฐานเป็นอย่างน้อย การรักษาความปลอดภัยในระดับที่สูงขึ้นอาจทำได้ยาก และอาจทำให้เกิดภาระเพิ่มเติมเนื่องจากการคัดลอกข้อมูลมากขึ้น กลไกสำคัญสำหรับการรักษาความปลอดภัยจากข้อยกเว้นคือfinallyข้อความ `dispose` หรือไวยากรณ์การจัดการข้อยกเว้น ที่คล้ายกัน ซึ่งช่วยให้มั่นใจได้ว่าโค้ดบางส่วนจะ ทำงาน เสมอเมื่อออกจากบล็อก รวมถึงกรณีที่มีข้อยกเว้นด้วย ภาษาโปรแกรมหลายภาษามีโครงสร้างที่ทำให้เรื่องนี้ง่ายขึ้น โดยเฉพาะอย่างยิ่งการใช้รูปแบบ `dispose`ซึ่งเรียกว่า ` dispose` using, `dispose.json` withหรือtry`dispose.json` ที่มีทรัพยากร

ตัวอย่าง

ลองพิจารณาประเภทเวกเตอร์อัจฉริยะ เช่น เวกเตอร์ในภาษา C++ หรือ Java เมื่อมีการเพิ่มรายการลงในเวกเตอร์เวกเตอร์จะต้องเพิ่ม รายการ นั้นลงในลิสต์ภายในของวัตถุและอัปเดตฟิลด์นับจำนวนที่ระบุว่ามีวัตถุอยู่กี่ชิ้นนอกจากนี้ อาจจำเป็นต้องจัดสรรหน่วยความจำใหม่หากความจุที่มีอยู่ไม่เพียงพอ std::vectorArrayListxvxv

ทางเลือกด้านความปลอดภัยที่เป็นข้อยกเว้น:

รับประกันไม่โยนทิ้ง
สามารถนำไปใช้ได้โดยการรับประกันว่าการจัดสรรหน่วยความจำจะไม่ล้มเหลว หรือโดยการกำหนดinsertพฤติกรรมของฟังก์ชันเมื่อการจัดสรรล้มเหลว (ตัวอย่างเช่น โดยให้ฟังก์ชันส่งคืนค่าบูลีนที่ระบุว่าการแทรกเกิดขึ้นหรือไม่)
ความปลอดภัยข้อยกเว้นที่แข็งแกร่ง
วิธีการนี้ใช้หลักการจัดสรรพื้นที่ก่อน จากนั้นจึงสลับบัฟเฟอร์หากไม่พบข้อผิดพลาด (ซึ่ง เป็นวิธี การคัดลอกและสลับ ) ในกรณีนี้ การแทรกข้อมูลxลงไปvจะสำเร็จ หรือvข้อมูลจะยังคงไม่เปลี่ยนแปลงแม้ว่าการจัดสรรพื้นที่จะล้มเหลวก็ตาม
ความปลอดภัยข้อยกเว้นขั้นพื้นฐาน
วิธีการนี้ดำเนินการโดยการรับประกันว่าฟิลด์จำนวนนับจะสะท้อนขนาดสุดท้ายของออบเจ็กvต์อย่างแน่นอน ตัวอย่างเช่น หากพบข้อผิดพลาดinsertฟังก์ชันอาจยกเลิกการจัดสรรหน่วยความจำทั้งหมดvและรีเซ็ตฟิลด์จำนวนนับเป็นศูนย์ ในกรณีที่ล้มเหลว จะไม่มีการรั่วไหลของทรัพยากร แต่vค่าเดิมของออบเจ็กต์จะไม่ถูกเก็บรักษาไว้
ไม่มีข้อยกเว้นด้านความปลอดภัย
ความล้มเหลวในการแทรกข้อมูลอาจนำไปสู่เนื้อหาที่เสียหายvค่าที่ไม่ถูกต้องในฟิลด์จำนวน หรือ การรั่ว ไหลของทรัพยากร
  • เฮิร์บ ซัตเตอร์: C++ ที่ยอดเยี่ยม: 47 ปริศนาทางวิศวกรรม ปัญหาการเขียนโปรแกรม และวิธีแก้ปัญหา, ปี 2000
  • Jon Kalb: การเขียนโค้ด C++ ที่ปลอดภัยจากข้อยกเว้นพร้อมด้วยการนำเสนอเรื่องความปลอดภัยจากข้อยกเว้นในงาน C++Now! 2012
  • หัวข้อสนทนาที่เกี่ยวข้องบน Stackoverflow: C++: คุณเขียนโค้ดที่ปลอดภัยจากข้อผิดพลาด (จริงๆ) หรือไม่
ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Exception_safety&oldid=1325204163 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ ความปลอดภัยที่เป็นข้อยกเว้น

ความปลอดภัยของข้อยกเว้นคือสถานะของโค้ดที่ทำงานได้อย่างถูกต้องเมื่อมีการโยนข้อยกเว้นเพื่อช่วยให้มั่นใจในความปลอดภัยของข้อยกเว้น นักพัฒนาไลบรารีมาตรฐาน...

ประวัติศาสตร์

ดังที่ David Abrahams เขียนไว้ว่า "ไม่มีใครเคยพูดถึง 'ความปลอดภัยจากข้อผิดพลาด' มาก่อนที่ C++ จะมีข้อยกเว้น" [ 3 ] คำนี้ปรากฏเป็นหัวข้อของเอกสารเผยแพร่ใน JTC1/SC22/WG21 ซึ่งเป็นคณะกรรมการมาตรฐาน C++ ตั้งแต่ปี 1994 [ 4 ]...

พื้นหลัง

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

การจำแนกประเภท

ไลบรารี มาตรฐาน C++ มีระดับความปลอดภัยของข้อยกเว้นหลายระดับ (เรียงลำดับจากความปลอดภัยมากที่สุดไปน้อยที่สุด): [ 8 ]