Której definicji preprocesora należy użyć do określenia sekcji kodu do debugowania?
Użyj #ifdef _DEBUG
lub #ifndef NDEBUG
czy jest lepszy sposób, aby to zrobić, np. #define MY_DEBUG
?
Myślę, że _DEBUG
jest to specyficzne dla Visual Studio, czy standard NDEBUG?
Tak, jest to standardowe makro z semantycznym „Not Debug” dla standardów C89, C99, C ++ 98, C ++ 2003, C ++ 2011, C ++ 2014. W
_DEBUG
standardach nie ma makr.Standard C ++ 2003 wysyła czytelnika na „stronę 326” w „17.4.2.1 Nagłówki” do standardu C.
W C89 (programiści C nazywali ten standard standardem C) w sekcji "4.2 DIAGNOSTYKA" powiedziano
Jeśli spojrzysz na znaczenie
_DEBUG
makr w Visual Studio https://msdn.microsoft.com/en-us/library/b0084kay.aspx , zobaczysz, że to makro jest automatycznie definiowane przez wybór wersji biblioteki środowiska uruchomieniowego języka.źródło
Polegam na tym
NDEBUG
, ponieważ jest to jedyny, którego zachowanie jest znormalizowane między kompilatorami i implementacjami (zobacz dokumentację standardowego makra assert). Logika negatywna to niewielki wzrost czytelności, ale jest to powszechny idiom, do którego można szybko się dostosować.Poleganie na czymś podobnym
_DEBUG
byłoby poleganiem na szczegółach implementacji konkretnego kompilatora i implementacji biblioteki. Inni kompilatorzy mogą, ale nie muszą, wybrać tę samą konwencję.Trzecią opcją jest zdefiniowanie własnego makra dla projektu, co jest całkiem rozsądne. Posiadanie własnego makra zapewnia przenośność między implementacjami i umożliwia włączanie lub wyłączanie kodu debugowania niezależnie od stwierdzeń. Chociaż, ogólnie rzecz biorąc, odradzam posiadanie różnych klas informacji debugowania, które są włączane w czasie kompilacji, ponieważ powoduje to wzrost liczby konfiguracji, które musisz zbudować (i przetestować) z prawdopodobnie niewielkimi korzyściami.
W przypadku dowolnej z tych opcji, jeśli używasz kodu innej firmy w ramach swojego projektu, musisz wiedzieć, jakiej konwencji używa.
źródło
#if !defined(NDEBUG)
<- @HostileFork czy nie to miałeś na myśli?#if
nie#ifdef
?#ifdef NDEBUG
... ale zwróć szczególną uwagę na logikę negatywną#if !defined(NDEBUG)
. W przeciwnym razie trochę trudno jest złapać n#ifndef NDEBUG
”Makro
NDEBUG
kontroluje, czyassert()
instrukcje są aktywne, czy nie.Moim zdaniem jest to niezależne od jakiegokolwiek innego debugowania - więc używam czegoś innego niż
NDEBUG
kontrolowanie informacji debugowania w programie. To, czego używam, różni się w zależności od frameworka, z którym pracuję; różne systemy mają różne makra włączające i używam tego, co jest odpowiednie.Jeśli nie ma frameworka, użyłbym nazwy bez początkowego podkreślenia; są one zwykle zarezerwowane dla „implementacji” i staram się unikać problemów z kolizjami nazw - podwójnie, gdy nazwa jest makrem.
źródło
#if
kontrolowanego kodu w drugiej.assert(huge_object.IsValid());
może być powolny, podczas gdyassert(ptr != nullptr);
prawdopodobnie nie. Zgadzam się z Jonathanem, że logowanie i śledzenie powinny prawdopodobnie różnić się od asercji, przynajmniej w większych projektach, ale nie myślę o logowaniu lub śledzeniu jako o kodzie debugowania, dlatego poprosiłem o wyjaśnienie.Bądź konsekwentny i nie ma znaczenia który. Również jeśli z jakiegoś powodu musisz współpracować z innym programem lub narzędziem przy użyciu określonego identyfikatora DEBUG, jest to łatwe
źródło
Niestety
DEBUG
jest mocno przeciążony. Na przykład, zaleca się, aby zawsze generować i zapisywać plik pdb dla wersji RELEASE. Co oznacza jedną z-Zx
flag i-DEBUG
opcję konsolidatora. Podczas gdy_DEBUG
odnosi się do specjalnych wersji debugowania biblioteki wykonawczej, takich jak wywołaniamalloc
ifree
. NastępnieNDEBUG
wyłączy asercje.źródło