มีปรัชญามากมายในสาขาวิศวกรรมซอฟต์แวร์ที่แตกต่างกันเกี่ยวกับวิธีที่ห้องสมุดควรจัดการกับข้อผิดพลาดหรือเงื่อนไขพิเศษอื่น ๆ บางอย่างที่ฉันเคยเห็น:
- ส่งคืนรหัสข้อผิดพลาดพร้อมผลลัพธ์ที่ส่งคืนโดยอาร์กิวเมนต์ตัวชี้ นี่คือสิ่งที่ PETSc ทำ
- ส่งคืนข้อผิดพลาดโดยค่า Sentinel ตัวอย่างเช่น malloc ส่งคืน NULL หากไม่สามารถจัดสรรหน่วยความจำได้
sqrt
จะส่งคืน NaN หากคุณส่งผ่านจำนวนลบเป็นต้นวิธีการนี้ใช้ในฟังก์ชัน libc จำนวนมาก - โยนข้อยกเว้น ใช้ในข้อตกลง II, Trilinos ฯลฯ
- ส่งคืนชนิดของตัวแปร ตัวอย่างเช่นฟังก์ชัน c ++ ที่ผลตอบแทนวัตถุของการพิมพ์
Result
ถ้ามันจะทำงานได้อย่างถูกต้องและใช้ประเภทเพื่ออธิบายวิธีการที่จะล้มเหลวก็จะกลับมาError
std::variant<Error, Result>
- ใช้ยืนยันและผิดพลาด ใช้ใน p4est และบางส่วนของการเขียนด้วยลายมือ
ปัญหาของแต่ละวิธี:
- การตรวจสอบข้อผิดพลาดทุกครั้งจะแนะนำรหัสพิเศษจำนวนมาก ค่าที่จะเก็บผลลัพธ์จะต้องประกาศก่อนเสมอแนะนำตัวแปรชั่วคราวจำนวนมากที่อาจใช้เพียงครั้งเดียว วิธีการนี้จะอธิบายถึงข้อผิดพลาดที่เกิดขึ้น แต่อาจเป็นเรื่องยากที่จะตัดสินว่าทำไมหรือสำหรับ call call stack ที่ใด
- กรณีข้อผิดพลาดง่ายต่อการเพิกเฉย ยิ่งไปกว่านั้นฟังก์ชั่นจำนวนมากไม่สามารถมีค่า Sentinel ที่มีความหมายได้หากช่วงของประเภทเอาต์พุตทั้งหมดเป็นผลลัพธ์ที่เป็นไปได้ ปัญหาเดียวกันจำนวนมากเช่น # 1
- ทำได้เฉพาะใน C ++, Python และอื่น ๆ ไม่ใช่ใน C หรือ Fortran สามารถเลียนแบบใน C ใช้ setjmp / เวทมนตร์ longjmp หรือlibunwind
- เป็นไปได้เฉพาะใน C ++, Rust, OCaml และอื่น ๆ ไม่ใช่ใน C หรือ Fortran สามารถเลียนแบบใน C โดยใช้เวทมนตร์คาถา
- เนื้อหาที่ให้ข้อมูลมากที่สุด แต่ถ้าคุณใช้วิธีการนี้เพื่อบอกว่าไลบรารี C ที่คุณเขียน Piper wrapper สำหรับข้อผิดพลาดโง่ ๆ เช่นการส่งดัชนีนอกขอบเขตไปยังอาร์เรย์จะทำให้ล่าม Python ขัดข้อง
คำแนะนำส่วนใหญ่บนอินเทอร์เน็ตเกี่ยวกับการจัดการข้อผิดพลาดนั้นเขียนจากมุมมองของระบบปฏิบัติการการพัฒนาแบบฝังหรือเว็บแอปพลิเคชัน ข้อขัดข้องไม่สามารถยอมรับได้และคุณต้องกังวลเกี่ยวกับความปลอดภัย การใช้งานทางวิทยาศาสตร์ไม่ได้มีปัญหาเหล่านี้ในระดับเกือบเท่ากันถ้าเลย
การพิจารณาอีกประการหนึ่งคือข้อผิดพลาดประเภทใดที่สามารถกู้คืนได้หรือไม่ malloc ล้มเหลวไม่สามารถกู้คืนได้และไม่ว่าในกรณีใดนักฆ่าหมดหน่วยความจำ OS จะไปถึงก่อนที่คุณจะทำ ดัชนีที่เกินขอบเขตสำหรับขนาดอาร์เรย์นั้นไม่สามารถกู้คืนได้ สำหรับฉันในฐานะผู้ใช้สิ่งที่ดีที่สุดที่ห้องสมุดสามารถทำได้คือขัดข้องด้วยข้อความแสดงข้อผิดพลาดที่ให้ข้อมูล ในอีกทางหนึ่งความล้มเหลวของการพูดการแก้ปัญหาเชิงเส้นซ้ำเพื่อมาบรรจบกันสามารถกู้คืนจากการใช้ตัวแก้การแยกตัวประกอบโดยตรง
ห้องสมุดวิทยาศาสตร์ควรรายงานข้อผิดพลาดและคาดหวังว่าจะจัดการได้อย่างไร ฉันรู้แน่นอนว่ามันขึ้นอยู่กับภาษาที่ใช้ในห้องสมุด แต่เท่าที่ฉันสามารถบอกได้ว่าสำหรับห้องสมุดที่มีประโยชน์มากพอคนจะต้องการเรียกมันจากภาษาอื่นที่ไม่ใช่ภาษาที่ใช้อยู่
นอกจากนี้ฉันคิดว่าวิธีที่ # 5 สามารถปรับปรุงได้อย่างมากสำหรับไลบรารี C หากกำหนดตัวชี้ฟังก์ชันตัวจัดการการยืนยันทั่วโลกซึ่งเป็นส่วนหนึ่งของ API สาธารณะ ตัวจัดการการยืนยันจะใช้ค่าเริ่มต้นในการรายงานไฟล์ / หมายเลขบรรทัดและการหยุดทำงาน การโยง C ++ สำหรับไลบรารีนี้จะกำหนดตัวจัดการการยืนยันใหม่ที่จะแทนที่ข้อยกเว้น C ++ แทน ในทำนองเดียวกันการผูก Python จะกำหนดตัวจัดการการยืนยันที่ใช้ CPython API เพื่อโยนข้อยกเว้น Python แต่ฉันไม่รู้ตัวอย่างที่ใช้วิธีนี้