2013-06-21 2 views
41

У меня есть выбор #defines в заголовке, который редактируется пользователем, и поэтому впоследствии я хочу проверить, существуют ли определения, если пользователь полностью их удаляет, например.Препроцессор проверяет, не определены ли несколько определений

#if defined MANUF && defined SERIAL && defined MODEL 
    // All defined OK so do nothing 
#else 
    #error "User is stoopid!" 
#endif 

Это отлично работает нормально, мне интересно, однако, если есть лучший способ проверить, если несколько определяет не на месте ... то есть что-то вроде:

#ifn defined MANUF || defined SERIAL ||.... // note the n in #ifn 

или, может быть

#if !defined MANUF || !defined SERIAL ||.... 

, чтобы удалить необходимость в пустой секции #if.

+3

FYI: 'defined' является оператор, вызывается как функция (точно так же, как 'sizeof'. Поэтому, если вы называете это функцией, ваш пример будет работать нормально. Кроме того, вы можете использовать большинство логических операторов ('==', '! =', '!', '||', '&&') в инструкциях препроцессора. –

+4

Это общий принцип булевой алгебры, который вы можете заменить '! (X && y)' на '(! X ||! Y)'. http://en.wikipedia.org/wiki/De_Morgan%27s_laws – Vicky

ответ

69
#if !defined(MANUF) || !defined(SERIAL) || !defined(MODEL) 
+0

Нужно ли добавлять парнеры или может быть "#if! defined MANUF || ..."? – TimK

+0

@TimK Из того, что написано выше, я бы сказал «да». Я вполне мог ошибаться; это просто предположение. – wizzwizz4

+2

На самом деле вы этого не делаете, но я бы рекомендовал его для удобочитаемости. https://godbolt.org/g/O48eun –

1

FWIW, @ Ответ SergeyL замечательный, но вот небольшой вариант для тестирования. Обратите внимание на изменение логического или логического и.

main.c имеет основную оболочку, как это:

#if !defined(TEST_SPI) && !defined(TEST_SERIAL) && !defined(TEST_USB) 
int main(int argc, char *argv[]) { 
    // the true main() routine. 
} 

spi.c, serial.c и usb.c имеют основные оберток для их соответствующего тестового кода, как это:

#ifdef TEST_USB 
int main(int argc, char *argv[]) { 
    // the main() routine for testing the usb code. 
} 

config.h который входит все с- файлов имеет такую ​​запись:

// Uncomment below to test the serial 
//#define TEST_SERIAL 


// Uncomment below to test the spi code 
//#define TEST_SPI 

// Uncomment below to test the usb code 
#define TEST_USB