Kniga-Online.club
» » » » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать бесплатно Linux программирование в примерах - Роббинс Арнольд. Жанр: Интернет год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

Эта методика работает; мы сами ее использовали и видели, как ее рекомендуют в учебниках. Однако, она может быть усовершенствована и дальше с уменьшением количества макросов до одного:

/* МЕТОДИКА 2 --- наиболее переносима; рекомендуется */

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

#ifdef MYAPPDEBUG

#define DPRINT(stuff) fprintf stuff

#else

#define DPRINT(stuff)

#endif

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

DPRINT((stderr, "myvar = %dn", myvar));

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

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

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

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

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

#ifdef MYAPPDEBUG

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

#else

#define DPRINT(mesg, ...)

#endif

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

DPRINT("myvar = %dn", myvar);

DPRINT("v1 = %d, v2 = %fn", v1, v2);

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

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

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

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

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

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

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

...

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

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

(gdb) <b>print RS_is_null</b>

No symbol &quot;RS_is_null&quot; in current context.

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

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

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

void set_RS() {

 ...

 RS_is_null = FALSE;

 if (RS-&gt;stlen == 0) {

  ...

  RS_is_null = TRUE;

  ...

  matchrec = rsnullscan;

 }

}

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

ЗАМЕЧАНИЕ. Начиная с GCC 3.1 и версии 5 GDB, если вы компилируете свою программу с опциями -gdwarf-2 и -g3, вы можете использовать макросы из-под GDB. В руководстве по GDB утверждается, что разработчики GDB надеются найти в конце концов более компактное представление для макросов, и что опция -g3 будет отнесена к группе -g.

Однако, использовать макросы таким способам позволяет лишь комбинация GCC, GDB и специальных опций: если вы не используете GCC (или если вы используете более старую версию), у вас все еще есть проблема. Мы придерживаемся своей рекомендации избегать по возможности таких макросов.

Проблема с макросами распространяется также и на фрагменты кода. Если макрос определяет несколько операторов, вы не можете установить контрольную точку в середине макроса. Это верно также для inline-функций C99 и С++: если компилятор заменяет тело inline-функции сгенерированным кодом, снова невозможно или трудно установить внутри него контрольную точку. Это имеет связь с нашим советом компилировать лишь с одной опцией -g; в этом случае компиляторы обычно не используют inline-функции.

Обычно с такими строками используется переменная, представляющая определенное состояние. Довольно просто, и это рекомендуется многими книгами по программированию на С, определять с помощью #define для таких состояний именованные константы. Например:

/* Различные состояния, в которых можно

   находиться при поиске конца записи. */

#define NOSTATE  1 /* сканирование еще не началось (все) */

#define INLEADER 2 /* пропуск начальных данных (RS = &quot;&quot;) */

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

Роббинс Арнольд читать все книги автора по порядку

Роббинс Арнольд - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Linux программирование в примерах отзывы

Отзывы читателей о книге Linux программирование в примерах, автор: Роббинс Арнольд. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*