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