Читаем Linux программирование в примерах полностью

#define DPRINT(stuff) fprintf stuff

#else

#define DPRINT(stuff)

#endif

/* В исходном файле приложения: */

DPRINT((stderr, "myvar = %d\n", myvar));

 /* Обратите внимание на двойные скобки */

Обратите внимание на то, как макрос извлекается с двумя наборами скобок! Поместив весь список аргументов для fprintf() в один аргумент, вам больше не нужно определять произвольное число отладочных макросов.

Если вы используете компилятор, удовлетворяющий стандарту С 1999 г., у вас есть дополнительный выбор, который дает наиболее чистый отладочный код:

/* МЕТОДИКА 3 --- самая чистая, но только для C99 */

/* В заголовочном файле приложения: */

#ifdef MYAPPDEBUG

#define DPRINT(mesg, ...) fprintf(stderr, mesg, __VA_ARGS__)

#else

#define DPRINT(mesg, ...)

#endif

/* В исходном файле приложения: */

DPRINT("myvar = %d\n", myvar);

DPRINT("v1 = %d, v2 = %f\n", v1, v2);

Стандарт С 1999 г. предусматривает варьирующий макрос (variadic macros); т.е. макрос, который может принимать переменное число аргументов. (Это похоже на варьирующую функцию, наподобие printf()). В макроопределении три точки '...' означают, что будет ноль или более аргументов. В теле макроса специальный идентификатор __VA_ARGS__ замещается предусмотренными аргументами, сколько бы их ни было.

Преимуществом этого механизма является то, что при извлечении отладочного макроса необходим лишь один набор скобок, что делает чтение кода значительно более естественным. Это также сохраняет возможность использовать всего одно имя макроса вместо нескольких, которые меняются в соответствии с числом аргументов. Недостатком является то, что компиляторы C99 пока еще доступны не так широко, что снижает переносимость этой конструкции. (Однако, эта ситуация будет со временем улучшаться.)

Рекомендация: Текущие версии GCC поддерживают варьирующие макросы. Таким образом, если вы знаете, что никогда не будете использовать для компилирования своих программ что-то, кроме GCC (или какого-нибудь другого компилятора C99), можете использовать механизм C99. Однако, на момент написания, компиляторы C99 все еще не являются обычным явлением. Поэтому, если ваш код должен компилироваться разными компиляторами, следует использовать макрос в стиле с двумя парами скобок.

<p>15.4.1.2. По возможности избегайте макросов с выражениями</p>

В общем, макросы препроцессора С являются довольно острой палкой с двумя концами. Они предоставляют вам большую мощь, но также и большую возможность пораниться самому.[169]

Обычно для эффективности или ясности можно видеть такие макросы:

#define RS_is_null (RS_node->var_value == Nnull_string)

...

if (RS_is_null || today == TUESDAY) ...

На первый взгляд, он выглядит замечательно. Условие 'RS_is_null' ясно и просто для понимания и абстрагирует внутренние детали проверки. Проблема возникает, когда вы пытаетесь вывести значение в GDB:

(gdb) print RS_is_null

No symbol "RS_is_null" in current context.

В таком случае нужно разыскать определение макроса и вывести развернутое значение.

Рекомендация: Для представления важных условий в своей программе используйте переменные, значения которых при изменении условий явным образом меняется в коде.

Вот сокращенный пример из io.c в дистрибутиве gawk:

void set_RS() {

 ...

 RS_is_null = FALSE;

 if (RS->stlen == 0) {

  ...

  RS_is_null = TRUE;

  ...

  matchrec = rsnullscan;

 }

}

После установки и сохранения RS_is_null ее можно протестировать в коде и вывести из-под отладчика.

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных