2009-09-10 5 views
3
#ifndef MACROS_NULLCHECK_H_ 
#define MACROS_NULLCHECK_H_ 

#include <assert.h> 

#define NULLCHECK(x) assert(x != (void *) 0); 

#endif 

Если я использовал этот стиль в качестве шаблона для объявления макросов, какие у вас были бы условия?C: Эффективное использование макросов

+1

пренебрегая ваш вопрос на данный момент: макрос 'NULLCHECK()' бесполезно: указатели скалярные типы и, следовательно, может использоваться в булевых контекстах; 'NULLCHECK (foo)' делает то же самое, что и 'assert (foo)' – Christoph

+0

@Christoph True, см. Http: // stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0/1296865 для большего. –

+1

@ Кристоф: Я не согласен: Утверждения должны быть Overt. Если это утверждение действительно вызывается, будет отображаться более открытое сообщение. т.е.: '' Нарушение утверждения: файл exe.c, строка $: (foo)! = (void *) 0 "' vs. '" Нарушение утверждения: файл exe.c, строка $: (foo) "' –

ответ

14
  • положить скобки вокруг аргумента (это предотвращает проблемы при прохождении выражения)

  • не ставят; в конце (использование будет более естественным)

    #define NULLCHECK (х) утверждают ((х)! = (пустота *) 0)

+0

@AProgrammer : Point # 2 кликов с моим мышлением тоже, спасибо кучи. –

0

Выглядит хорошо. Это образец, который я использую много.

3

Одно изменение, которое я мог бы сделать было бы комментировать закрытие #endif:

#endif // MACROS_NULLCHECK_H_ 

это делает его легче понять, что это #endif делает там, когда файл становится больше, чем экран.

3

Вообще говоря, вы должны всегда ставить аргументы макрокоманд в скобках в разложении, то есть в вашем случае

assert((x) != (void*) 0) 

Это происходит потому, что если вы не то какое-либо выражения (а не простые переменных), которые вы передаете in может испортить переменное расширение.

Я хотел бы также предположить, что вы НЕ поставить точку с запятой в конце макроопределения, так что вы должны назвать его как

NULLCHECK(pSomething); 

который только выглядит более C-подобный & в соответствии с остальной части вашего кода.

1

Некоторые хорошие макро практики от CERT C Secure Coding Wiki:

PRE00-C. Предпочитают встроенные или статические функции для функциональных макросов
PRE01-C. Используйте круглые скобки внутри макросов вокруг имен параметров.
PRE02-C. Списки замены макросов должны быть заключены в скобки
PRE03-C. Предпочитают typedefs для определения для типов кодирования
PRE10-C. Оберните макросы нескольких операторов в цикле do-while
PRE11-C. Не завершайте определение макроса одного оператора точкой с запятой
PRE31-C. Никогда не вызывать небезопасный макрос с аргументами, содержащими назначение, приращение, декремент, нестабильный доступ или вызов функции.
PRE32-C. Не используйте директивы препроцессора внутри макроса аргументы

0

Для исполнения ; используйте

#define NULLCHECK(x) do { assert((X)); } while (0) 
+3

Дословная идиома хороша, когда это необходимо; пример не является убедительным. –

Смежные вопросы