หลักเกณฑ์ C ++ Core มีกฎES.20: เริ่มต้นวัตถุเสมอ
หลีกเลี่ยงข้อผิดพลาดที่ใช้ก่อนกำหนดและพฤติกรรมที่ไม่ได้กำหนดไว้ หลีกเลี่ยงปัญหาเกี่ยวกับความเข้าใจในการเริ่มต้นที่ซับซ้อน ลดความซับซ้อนของการ refactoring
แต่กฎนี้ไม่ได้ช่วยในการค้นหาข้อบกพร่องมันเพียงซ่อนพวกเขา
สมมติว่าโปรแกรมมีพา ธ การประมวลผลซึ่งใช้ตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้น มันเป็นข้อผิดพลาด พฤติกรรมที่ไม่ได้กำหนดไว้นอกจากนี้ยังหมายความว่ามีบางอย่างผิดปกติและโปรแกรมอาจไม่ตรงตามข้อกำหนดของผลิตภัณฑ์ เมื่อมันถูกนำไปใช้กับการผลิตอาจมีการสูญเสียเงินหรือแย่ลง
เราจะตรวจสอบข้อบกพร่องได้อย่างไร เราเขียนแบบทดสอบ แต่การทดสอบไม่ครอบคลุมเส้นทางการดำเนินการ 100% และการทดสอบจะไม่ครอบคลุม 100% ของอินพุตโปรแกรม ยิ่งไปกว่านั้นแม้การทดสอบจะครอบคลุมเส้นทางการดำเนินการที่ผิดปกติ แต่ก็ยังสามารถผ่านได้ มันไม่ได้กำหนดพฤติกรรมหลังจากทั้งหมดตัวแปร uninitialized สามารถมีค่าที่ค่อนข้างถูกต้อง
แต่นอกเหนือจากการทดสอบของเราเรามีคอมไพเลอร์ที่สามารถเขียนอะไรบางอย่างเช่น 0xCDCDCDCD ไปยังตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้น สิ่งนี้จะช่วยปรับปรุงอัตราการตรวจจับของการทดสอบเล็กน้อย
ยิ่งไปกว่านั้น - มีเครื่องมือเช่น Address Sanitizer ที่จะอ่านค่าหน่วยความจำที่ไม่ได้กำหนดค่าเริ่มต้นทั้งหมด
และในที่สุดก็มีเครื่องวิเคราะห์แบบสแตติกซึ่งสามารถดูโปรแกรมและบอกว่ามีการอ่านก่อนตั้งค่าบนพา ธ การเรียกใช้งานนั้น
ดังนั้นเราจึงมีเครื่องมือที่ทรงพลังมากมาย แต่ถ้าเราเริ่มต้นตัวแปร - sanitizers ไม่พบอะไรเลย
int bytes_read = 0;
my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*);
// bytes_read is not changed on read error.
// It's a bug of "my_read", but detection is suppressed by initialization.
buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here.
// Another bug: use empty buffer after read error.
use(buffer);
มีกฎอีกข้อหนึ่ง - หากการเรียกใช้โปรแกรมพบข้อบกพร่องโปรแกรมควรจะตายโดยเร็วที่สุด ไม่จำเป็นต้องทำให้มันมีชีวิตอีกต่อไปเพียงแค่ผิดพลาดเขียน crashdump มอบให้วิศวกรเพื่อตรวจสอบ
การเริ่มต้นตัวแปรต่างกันตรงข้าม - โปรแกรมนั้นยังคงมีชีวิตอยู่เมื่อมันจะได้รับการแบ่งส่วนผิดอย่างอื่น
\0
มันเป็นรถ หากมีการบันทึกไว้ว่าจะไม่จัดการกับสิ่งนั้นรหัสการโทรของคุณจะเป็นรถ หากคุณแก้ไขรหัสโทรศัพท์ของคุณเพื่อตรวจสอบbytes_read==0
ก่อนใช้งานคุณจะกลับไปยังที่ที่คุณเริ่ม: รหัสของคุณจะสกปรกถ้าคุณไม่เริ่มต้นbytes_read
ปลอดภัยหากคุณทำ ( โดยปกติฟังก์ชั่นควรจะเติมพารามิเตอร์ของพวกเขาแม้ในกรณีที่มีข้อผิดพลาด : ไม่จริง ๆ บ่อยครั้งที่ผลลัพธ์ที่ได้จะถูกทิ้งไว้ตามลำพังหรือไม่ได้กำหนดไว้)
err_t
ส่งคืนโดยmy_read()
? หากมีข้อบกพร่องที่ใดก็ได้ในตัวอย่างนั่นก็คือ
bytes_read
ไม่เปลี่ยนแปลง (เก็บเป็นศูนย์ไว้) เหตุใดจึงเป็นข้อบกพร่อง โปรแกรมสามารถดำเนินการต่อในลักษณะที่มีสติได้ตราบใดที่โปรแกรมไม่คาดว่าจะเกิดขึ้นในbytes_read!=0
ภายหลัง ดังนั้นมันก็เป็น sanitizers ที่ดีอย่าบ่น ในทางกลับกันเมื่อbytes_read
ไม่ได้เริ่มต้นก่อนโปรแกรมจะไม่สามารถที่จะดำเนินการในลักษณะที่มีสติจึงไม่ได้เริ่มต้นbytes_read
จริงแนะนำข้อผิดพลาดที่ไม่ได้มีไว้ก่อน