ฉันมักจะเพิ่มการยืนยันจำนวนมากให้กับโค้ด C ++ ของฉันเพื่อให้การดีบักง่ายขึ้นโดยไม่ส่งผลกระทบต่อประสิทธิภาพของการสร้างรุ่น ตอนนี้assert
เป็นมาโคร C บริสุทธิ์ที่ออกแบบโดยไม่คำนึงถึงกลไก C ++
ในทางกลับกัน C ++ กำหนดstd::logic_error
ซึ่งหมายถึงการโยนในกรณีที่มีข้อผิดพลาดในตรรกะของโปรแกรม (ดังนั้นชื่อ) การโยนอินสแตนซ์อาจเป็นทางเลือกที่สมบูรณ์แบบของ C ++ assert
มากกว่า
ปัญหาคือassert
และabort
ทั้งสองยุติโปรแกรมทันทีโดยไม่ต้องเรียกผู้ทำลายดังนั้นการข้ามการล้างข้อมูลในขณะที่การทิ้งข้อยกเว้นด้วยตนเองจะเพิ่มต้นทุนรันไทม์โดยไม่จำเป็น วิธีหนึ่งในการแก้ปัญหานี้คือการสร้างมาโครการยืนยันของตัวเองSAFE_ASSERT
ซึ่งใช้งานได้เหมือนกับคู่ C แต่จะมีข้อยกเว้นสำหรับความล้มเหลว
ฉันนึกถึงความคิดเห็นสามประการเกี่ยวกับปัญหานี้:
- ยึดมั่นในการยืนยันของ C เนื่องจากโปรแกรมถูกยกเลิกทันทีจึงไม่สำคัญว่าการเปลี่ยนแปลงจะถูกยกเลิกอย่างถูกต้องหรือไม่ นอกจากนี้การใช้
#define
s ใน C ++ ก็แย่พอ ๆ กัน - โยนข้อยกเว้นและจับมันใน main () การอนุญาตให้รหัสข้ามตัวทำลายในสถานะใด ๆ ของโปรแกรมถือเป็นการปฏิบัติที่ไม่ดีและต้องหลีกเลี่ยงค่าใช้จ่ายทั้งหมดดังนั้นจึงมีการเรียกร้องให้ยุติ () หากมีการโยนข้อยกเว้นจะต้องถูกจับ
- ทิ้งข้อยกเว้นและให้มันยุติโปรแกรม ข้อยกเว้นในการยุติโปรแกรมนั้นไม่เป็นไรและเนื่องจาก
NDEBUG
สิ่งนี้จะไม่เกิดขึ้นในรุ่นสร้าง การจับเป็นสิ่งที่ไม่จำเป็นและเปิดเผยรายละเอียดการนำโค้ดภายในไปmain()
ใช้
มีคำตอบที่ชัดเจนสำหรับปัญหานี้หรือไม่? อ้างอิงมืออาชีพใด ๆ ?
แก้ไข:แน่นอนว่าการข้ามผู้ทำลายล้างคือพฤติกรรมที่ไม่ได้กำหนด
logic_error
เป็นข้อผิดพลาดทางตรรกะ ข้อผิดพลาดในตรรกะของโปรแกรมเรียกว่าข้อบกพร่อง คุณไม่ได้แก้บั๊กด้วยการทิ้งข้อยกเว้น