ฉันรู้ว่าในขณะที่คำถามไม่มีแท็กภาษา แต่ก็อาจพูดถึง "กาแฟภาษา" โดยปริยาย แต่เพื่อความสมบูรณ์ฉันต้องการพูดถึงฉันทามติที่ค่อนข้างชัดเจนในโลก C ++
มีสามสิ่งที่โปรแกรมเมอร์ C ++ มักสนใจ:
- มันจะมีค่าใช้จ่ายเป็นศูนย์ในการสร้างที่ปรับให้เหมาะสมหรือไม่? (นั่นคือมันสามารถ "รวบรวม" หรือไม่)
- ฉันสามารถใช้มันเพื่อดักจับตัวดีบั๊กที่จุดที่ตรวจพบข้อผิดพลาดได้หรือไม่?
- ฉันสามารถใช้มันเพื่อรายงานปัญหาจากฟังก์ชั่นที่ประกาศได้
noexcept
หรือไม่?
ในอดีตฉันได้เข้าหาปัญหาแรกโดยการเขียนโค้ดแบบนี้
int
factorial(const int n)
{
if (CHECK_ARGS)
{
if (n < 0)
throw std::invalid_argument {"n < 0"};
}
int fac = 1;
for (int i = 2; i <= n; ++i)
fac *= i;
return fac;
}
ซึ่งCHECK_ARGS
เป็น#define
วันที่จะคงที่เวลารวบรวมเพื่อเรียบเรียงสมบูรณ์อาจขจัดข้อโต้แย้งรหัสการตรวจสอบทั้งหมดในการเพิ่มประสิทธิภาพสร้าง (ฉันไม่ได้บอกว่าการรวบรวมเช็คเอาท์เป็นสิ่งที่ดีโดยทั่วไป แต่ฉันเชื่อว่าผู้ใช้ควรมีตัวเลือกในการรวบรวมพวกเขาออก)
if
ผมยังคงชอบเกี่ยวกับการแก้ปัญหานี้ว่ารหัสการตรวจสอบการโต้แย้งคือการจัดกลุ่มเห็นได้อย่างชัดเจนด้วยกันลงใน อย่างไรก็ตามปัญหาที่สองและสามไม่ได้รับการแก้ไขโดยสิ่งนี้ ดังนั้นตอนนี้ฉันเอนตัวไปอีกครั้งเพื่อใช้assert
แมโครเพื่อตรวจสอบอาร์กิวเมนต์
เพิ่มมาตรฐานการเข้ารหัสเห็นด้วยกับเรื่องนี้:
ข้อผิดพลาดของโปรแกรมเมอร์คืออะไร
ในฐานะนักพัฒนาซอฟต์แวร์ถ้าฉันละเมิดเงื่อนไขของห้องสมุดที่ใช้อยู่ฉันไม่ต้องการให้กองคลี่คลาย สิ่งที่ฉันต้องการคือการถ่ายโอนข้อมูลหลักหรือเทียบเท่า - วิธีการตรวจสอบสถานะของโปรแกรม ณ จุดที่แน่นอนที่ตรวจพบปัญหา ที่มักจะหมายถึงassert()
หรืออะไรทำนองนั้น
มีการพูดคุยที่น่าสนใจมากที่ John Lakos มอบให้ที่CppCon'14หัวข้อการเขียนโปรแกรมการป้องกัน Done Right ( ตอนที่ 1 , ตอนที่ 2 ) ในส่วนแรกของการพูดคุยของเขาเขากล่าวถึงทฤษฎีสัญญาและพฤติกรรมที่ไม่ได้กำหนด ในส่วนที่สองเขานำเสนอสิ่งที่ฉันพิจารณาข้อเสนอที่ดีมากสำหรับการตรวจสอบการโต้แย้งอย่างเป็นระบบ ในสาระสำคัญเขาเสนอมาโครการยืนยันที่อนุญาตให้ผู้ใช้เลือกงบประมาณ (ในแง่ของการใช้งาน CPU) เท่าใดเธอยินดีที่จะบริจาคให้กับห้องสมุดเพื่อตรวจสอบการโต้แย้งและห้องสมุดใช้ประโยชน์จากงบประมาณนั้นอย่างชาญฉลาด นอกจากนี้ผู้ใช้ยังสามารถติดตั้งฟังก์ชั่นการจัดการข้อผิดพลาดทั่วโลกที่จะถูกเรียกในกรณีที่ตรวจพบสัญญาที่เสียหาย
เกี่ยวกับแง่มุมที่ฟังก์ชั่นเป็นส่วนตัวฉันไม่คิดว่านี่หมายความว่าเราไม่ควรตรวจสอบข้อโต้แย้งของมัน เราอาจเชื่อถือรหัสของเราเองมากกว่าที่จะไม่ละเมิดสัญญาของฟังก์ชั่นภายใน แต่เราก็รู้ว่าเราไม่ได้สมบูรณ์แบบเช่นกัน การตรวจสอบอาร์กิวเมนต์ในฟังก์ชันภายในมีประโยชน์ในการตรวจจับข้อบกพร่องของเราเองเช่นเดียวกับในฟังก์ชั่นสาธารณะสำหรับตรวจจับข้อบกพร่องในรหัสลูกค้า