Dlaczego ludzie używają #ifdef do testowania flag obiektów?
Ludziepolecić#ifdef
do kompilacji warunkowej z dużym marginesem. ZAszukać#ifdef
uzasadnia, że jego stosowanie jest wszechobecne.
Jeszcze#ifdef NAME
(lub równoważnie#if defined(NAME)
I powiązane#ifndef NAME
(i#if !defined(NAME)
) mają poważną wadę:
#ifndef IS_SPECIAL
#error You're not special enough
#endif
source.cpp#include "header.h"
gcc -DIS_SPECIAL source.cpp
przejdzie, oczywiście, jak będzie
source1.cpp#define IS_SPECIAL 1
#include "header.h"
Ale tak będzie
source0.cpp#define IS_SPECIAL 0
#include "header.h"
co jest całkiem złe. Niektóre kompilatory C ++ przekazały przetworzony plikC tryb (ze względu na rozszerzenie lub opcję wiersza polecenia) skutecznie to robi#define __cplusplus 0
. Widziałem, jak coś się załamuje
#ifdef __cplusplus
extern "C" {
#endif
/* ... */
#ifdef __cplusplus
}
#endif
został przetworzonyC tryb, gdzieextern "C"
jest nieprawidłową składnią, ponieważ__cplusplus
został automatycznie zdefiniowany0
.
Z drugiej strony, działa to poprawnie dla wszystkich kompilatorów:
#if __cplusplus
extern "C" {
#endif
/* ... */
#if __cplusplus
}
#endif
Dlaczego ludzie nadal korzystają#ifdef
w tym scenariuszu? Czy po prostu tego nie wiedzą#if
działa doskonale na niezdefiniowanych nazwach? Lubczy istnieje rzeczywista wada#if
vs#ifdef
do kompilacji warunkowej?
Oczywiście,#ifdef
ma poprawne zastosowania, takie jak podanie wartości domyślnych dla konfigurowalnych parametrów:
#ifndef MAX_FILES
#define MAX_FILES 64
#endif
Omawiam tylko przypadek testowania flag.