С:Эффективное использование макросов
Вопрос
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
Если бы я использовал приведенный выше стиль в качестве шаблона для объявления макросов, какие бы у вас были оговорки?
Решение
поместите аргумент в круглые скобки (это предотвращает проблемы при передаче выражений)
не ставь;в конце (использование будет более естественным)
#define NULLCHECK(x) Assert((x) != (void*)0)
Другие советы
Вообще говоря, в расширении всегда следует указывать аргументы макроса в скобках, т. е. в вашем случае
assert((x) != (void*) 0)
Это потому, что если вы этого не сделаете, то любые выражения (а не простые переменные), которые вы передаете, могут испортить расширение переменной.
Я бы также посоветовал вам не ставить точку с запятой в конце определения макроса, так что вы должны называть его как
NULLCHECK(pSomething);
, который выглядит как C-like & amp; в соответствии с остальным кодом.
Одно из изменений, которое я мог бы сделать, это прокомментировать закрывающий #endif
:
#endif // MACROS_NULLCHECK_H_
Это упрощает понимание того, что делает #endif
там, когда файл длиннее экрана.
Некоторые хорошие макропрактики из CERT C Безопасное кодирование Wiki:
ПРЕ00-С.Предпочитайте встроенные или статические функции функциональным макросам.
PRE01-C.Используйте круглые скобки внутри макросов вокруг имен параметров.
PRE02-C.Списки замены макросов должны быть заключены в круглые скобки.
PRE03-C.Предпочитайте определения типов, а не определения типов кодирования.
PRE10-C.Оберните макросы с несколькими операторами в цикл do- while
PRE11-C.Не завершайте определение макроса с одним оператором точкой с запятой.
PRE31-C.Никогда не вызывайте небезопасный макрос с аргументами, содержащими присваивание, увеличение, уменьшение, непостоянный доступ или вызов функции.
ПРЕ32-С.Не используйте директивы препроцессора внутри аргументов макроса.
Хорошо выглядит. Это шаблон, который я часто использую.
Чтобы применить ;
, используйте
#define NULLCHECK(x) do { assert((X)); } while (0)