Definisi preprocessor mana yang harus digunakan untuk menentukan bagian debug kode?
Gunakan #ifdef _DEBUG
atau #ifndef NDEBUG
atau adakah cara yang lebih baik untuk melakukannya, misalnya #define MY_DEBUG
?
Saya pikir _DEBUG
Visual Studio spesifik, apakah standar NDEBUG?
Ya itu adalah makro standar dengan semantic "Not Debug" untuk C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014 standar. Tidak ada
_DEBUG
makro dalam standar.Standar C ++ 2003 mengirim pembaca di "halaman 326" di "17.4.2.1 Header" ke standar C.
Dalam C89 (programmer C menyebut standar ini sebagai standar C) di bagian "4.2 DIAGNOSTIK" dikatakan
Jika melihat arti
_DEBUG
makro di Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspx maka akan terlihat, bahwa makro ini secara otomatis ditentukan oleh сhoice versi perpustakaan runtime bahasa Anda.sumber
Saya mengandalkan
NDEBUG
, karena itu adalah satu-satunya yang perilakunya distandardisasi di seluruh kompiler dan implementasi (lihat dokumentasi untuk makro pernyataan standar). Logika negatif adalah speedbump keterbacaan kecil, tapi itu adalah idiom umum yang dapat Anda adaptasi dengan cepat.Untuk bergantung pada sesuatu seperti
_DEBUG
akan bergantung pada detail implementasi dari kompiler dan implementasi perpustakaan tertentu. Kompiler lain mungkin atau mungkin tidak memilih konvensi yang sama.Opsi ketiga adalah mendefinisikan makro Anda sendiri untuk proyek Anda, yang cukup masuk akal. Memiliki makro Anda sendiri memberi Anda portabilitas di seluruh implementasi dan memungkinkan Anda untuk mengaktifkan atau menonaktifkan kode debug Anda secara independen dari pernyataan. Meskipun, secara umum, saya menyarankan agar tidak memiliki kelas informasi debug yang berbeda yang diaktifkan pada waktu kompilasi, karena hal itu menyebabkan peningkatan jumlah konfigurasi yang harus Anda bangun (dan uji) untuk manfaat yang bisa dibilang kecil.
Dengan salah satu opsi ini, jika Anda menggunakan kode pihak ketiga sebagai bagian dari proyek Anda, Anda harus mengetahui konvensi mana yang digunakannya.
sumber
#if !defined(NDEBUG)
<- @HostileFork bukankah itu yang Anda maksud?#if
bukan#ifdef
?#ifdef NDEBUG
... tapi kemudian minta perhatian khusus pada logika negatif dengan#if !defined(NDEBUG)
. Kalau tidak, agak sulit untuk menangkap#ifndef NDEBUG
"Makro
NDEBUG
mengontrol apakahassert()
pernyataan aktif atau tidak.Dalam pandangan saya, itu terpisah dari debugging lain - jadi saya menggunakan sesuatu selain
NDEBUG
untuk mengontrol informasi debug dalam program. Apa yang saya gunakan bervariasi, tergantung pada kerangka kerja saya; sistem yang berbeda memiliki makro yang memungkinkan yang berbeda, dan saya menggunakan apa pun yang sesuai.Jika tidak ada kerangka kerja, saya akan menggunakan nama tanpa garis bawah utama; mereka cenderung dicadangkan untuk 'implementasi' dan saya mencoba untuk menghindari masalah dengan tabrakan nama - jadi ketika nama adalah makro.
sumber
#if
-kontrol kode di yang lain.assert(huge_object.IsValid());
mungkin lambat sementaraassert(ptr != nullptr);
mungkin tidak. Saya setuju dengan Jonathan bahwa logging dan tracing mungkin harus berbeda dari pernyataan, setidaknya dalam proyek yang lebih besar, tetapi saya tidak menganggap logging atau tracing sebagai kode debug, itulah sebabnya saya meminta klarifikasi.Konsisten dan tidak masalah yang mana. Juga jika karena alasan tertentu Anda harus melakukan interop dengan program atau alat lain menggunakan pengenal DEBUG tertentu itu mudah dilakukan
sumber
Sayangnya
DEBUG
kelebihan beban. Misalnya, disarankan untuk selalu menghasilkan dan menyimpan file pdb untuk RELEASE build. Yang berarti salah satu opsi-Zx
flag, dan-DEBUG
linker. Sementara_DEBUG
berkaitan dengan versi debug khusus perpustakaan runtime seperti panggilan kemalloc
danfree
. MakaNDEBUG
akan menonaktifkan asersi.sumber