ควรใช้ตัวประมวลผลล่วงหน้าชุดใดเพื่อระบุส่วนการดีบักของรหัส
ใช้#ifdef _DEBUG
หรือ#ifndef NDEBUG
หรือมีวิธีที่ดีกว่าที่จะทำเช่น#define MY_DEBUG
?
ฉันคิดว่า_DEBUG
เป็น Visual Studio เฉพาะมาตรฐาน NDEBUG หรือไม่
ควรใช้ตัวประมวลผลล่วงหน้าชุดใดเพื่อระบุส่วนการดีบักของรหัส
ใช้#ifdef _DEBUG
หรือ#ifndef NDEBUG
หรือมีวิธีที่ดีกว่าที่จะทำเช่น#define MY_DEBUG
?
ฉันคิดว่า_DEBUG
เป็น Visual Studio เฉพาะมาตรฐาน NDEBUG หรือไม่
คำตอบ:
Visual Studio กำหนด_DEBUG
เมื่อคุณระบุ/MTd
หรือ/MDd
ตัวเลือกNDEBUG
ปิดการใช้งานการยืนยันมาตรฐาน C ใช้พวกเขาในเวลาที่เหมาะสมเช่น_DEBUG
ถ้าคุณต้องการรหัสแก้จุดบกพร่องของคุณเพื่อให้สอดคล้องกับเทคนิค MS CRT แก้จุดบกพร่องและถ้าคุณต้องการเพื่อให้สอดคล้องกับNDEBUG
assert()
หากคุณกำหนดมาโครการดีบักของคุณเอง (และคุณไม่แฮกคอมไพเลอร์หรือรันไทม์ C) ให้หลีกเลี่ยงการเริ่มต้นชื่อด้วยเครื่องหมายขีดล่างเนื่องจากสิ่งเหล่านี้สงวนไว้
เป็นมาตรฐาน NDEBUG หรือไม่
ใช่มันเป็นแมโครมาตรฐานที่มีความหมาย "Not Debug" สำหรับ C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014 ไม่มี_DEBUG
มาโครในมาตรฐาน
มาตรฐาน C ++ 2003 ส่งผู้อ่านไปที่ "หน้า 326" ที่ "17.4.2.1 ส่วนหัว" ถึงมาตรฐาน C
NDEBUG นั้นคล้ายกันกับนี่เหมือนกับไลบรารี C มาตรฐาน
ใน C89 (โปรแกรมเมอร์ C เรียกว่ามาตรฐานนี้เป็นมาตรฐาน C) ในส่วน "4.2 DIAGNOSTICS"
http://port70.net/~nsz/c/c89/c89-draft.html
ถ้า NDEBUG ถูกกำหนดให้เป็นชื่อแมโครที่จุดในไฟล์ต้นฉบับที่มีอยู่แมโคร assert จะถูกกำหนดอย่างง่าย ๆ ดังนี้
#define assert(ignore) ((void)0)
หากดูความหมายของ_DEBUG
มาโครใน Visual Studio
https://msdn.microsoft.com/en-us/library/b0084kay.aspx
จะเห็นได้ว่ามาโครนี้ถูกกำหนดโดยอัตโนมัติโดยเวอร์ชันไลบรารีรันไทม์ภาษาของคุณ
ฉันพึ่งพาNDEBUG
เพราะมันเป็นพฤติกรรมเดียวที่มีมาตรฐานในคอมไพเลอร์และการใช้งาน (ดูเอกสารประกอบสำหรับแมโครยืนยันมาตรฐาน) ตรรกะเชิงลบคือความเร็วในการอ่านเล็กน้อย แต่เป็นสำนวนทั่วไปที่คุณสามารถปรับให้เข้ากับได้อย่างรวดเร็ว
การพึ่งพาบางสิ่งเช่น_DEBUG
นั้นก็คือการพึ่งพารายละเอียดการใช้งานของคอมไพเลอร์และการใช้งานไลบรารี คอมไพเลอร์อื่น ๆ อาจจะหรืออาจจะไม่เลือกแบบแผนเดียวกัน
ตัวเลือกที่สามคือการกำหนดแมโครของคุณเองสำหรับโครงการของคุณซึ่งค่อนข้างสมเหตุสมผล การมีมาโครของคุณเองจะช่วยให้คุณพกพาระหว่างการติดตั้งใช้งานและช่วยให้คุณสามารถเปิดหรือปิดการใช้งานรหัสการดีบักได้อย่างอิสระ แม้ว่าโดยทั่วไปแล้วฉันแนะนำไม่ให้มีคลาสที่แตกต่างกันของข้อมูลการดีบักที่เปิดใช้งานในเวลารวบรวมเนื่องจากจะทำให้จำนวนการกำหนดค่าที่คุณต้องสร้าง (และทดสอบ) เพิ่มขึ้นเพื่อประโยชน์เล็ก ๆ น้อย ๆ
ด้วยตัวเลือกใด ๆ เหล่านี้หากคุณใช้รหัสของบุคคลที่สามเป็นส่วนหนึ่งของโครงการของคุณคุณจะต้องทราบถึงข้อตกลงที่ใช้
#if !defined(NDEBUG)
<- @HostileFork นั่นไม่ใช่สิ่งที่คุณหมายถึงเหรอ? #if
ไม่ใช่#ifdef
เหรอ
#ifdef NDEBUG
... #if !defined(NDEBUG)
แต่แล้วเรียกความสนใจเป็นพิเศษกับตรรกะเชิงลบด้วยไม่งั้นมันก็ยากที่จะจับตัว n ใน#ifndef NDEBUG
"
แมโครNDEBUG
ควบคุมว่าassert()
ข้อความสั่งทำงานหรือไม่
ในมุมมองของฉันที่แยกจากการดีบักอื่น ๆ - ดังนั้นฉันใช้สิ่งอื่นที่ไม่ใช่ NDEBUG
การควบคุมข้อมูลการดีบักในโปรแกรม สิ่งที่ฉันใช้แตกต่างกันไปขึ้นอยู่กับกรอบที่ฉันทำงานด้วย ระบบที่แตกต่างกันมีแมโครที่เปิดใช้งานที่แตกต่างกันและฉันใช้สิ่งที่เหมาะสม
หากไม่มีกรอบฉันจะใช้ชื่อโดยไม่มีขีดเส้นใต้ ผู้ที่มีแนวโน้มที่จะถูกสงวนไว้ที่ 'การใช้งาน' และฉันพยายามหลีกเลี่ยงปัญหาเกี่ยวกับการชนชื่อ - สองเท่าดังนั้นเมื่อชื่อเป็นมาโคร
#if
รหัสที่ควบคุมได้ในอีกประเภทหนึ่ง assert(huge_object.IsValid());
อาจช้าในขณะที่assert(ptr != nullptr);
อาจไม่ใช่ ฉันเห็นด้วยกับโจนาธานว่าการบันทึกและการติดตามควรจะแตกต่างจากการยืนยันอย่างน้อยในโครงการขนาดใหญ่ แต่ฉันไม่คิดว่าการบันทึกหรือการสืบค้นกลับเป็นรหัสดีบักซึ่งเป็นสาเหตุที่ฉันขอคำชี้แจง
มีความสอดคล้องและมันไม่สำคัญว่าจะเป็นที่หนึ่ง นอกจากนี้หากมีเหตุผลบางอย่างที่คุณต้องทำงานร่วมกับโปรแกรมหรือเครื่องมืออื่นโดยใช้ตัวระบุ DEBUG บางตัวมันก็สามารถทำได้
#ifdef THEIRDEBUG
#define MYDEBUG
#endif //and vice-versa
น่าเสียดายที่DEBUG
มีการใช้งานมากเกินไป ตัวอย่างเช่นแนะนำให้สร้างและบันทึกไฟล์ pdb สำหรับการสร้าง RELEASE เสมอ ซึ่งหมายถึงหนึ่งใน-Zx
แฟล็กและ-DEBUG
ตัวเลือกลิงก์ ในขณะที่_DEBUG
เกี่ยวข้องกับการแก้ปัญหารุ่นพิเศษของไลบรารีรันไทม์เช่นโทรไปและmalloc
free
จากนั้นNDEBUG
จะปิดใช้งานการยืนยัน