С:Эффективное использование макросов

StackOverflow https://stackoverflow.com/questions/1404470

  •  05-07-2019
  •  | 
  •  

Вопрос

#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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top