Чтение онлайн

на главную - закладки

Жанры

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

Роббинс Арнольд

Шрифт:

Вот сокращенный пример из

io.c
в дистрибутиве
gawk
:

void set_RS {

 ...

 RS_is_null = FALSE;

 if (RS->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 = "") */

#define INDATA 3 /* в теле записи (все) */

#define INTERM 4 /* терминатор сканирования (RS = RS = regexp) */

int state;

...

state = NOSTATE;

...

state = INLEADER;

...

if (state != INTERM) ...

На уровне исходного кода это выглядит замечательно. Но опять-таки, есть проблема, когда вы пытаетесь просмотреть код из GDB:

(gdb) print state

$1 = 2

Здесь вы также вынуждены возвращаться

обратно и смотреть в заголовочный файл, чтобы выяснить, что означает 2. Какова же альтернатива?

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

Пример, тоже из

io.c
в
gawk
:

typedef enum scanstate {

 NOSTATE, /* сканирование еще не начато (все) */

 INLEADER, /* пропуск начальных данных (RS = "") */

 INDATA, /* в теле записи (все) */

 INTERM, /* терминатор сканирования (RS = "", RS = regexp) */

} SCANSTATE;

SCANSTATE state;

/* ... остальной код без изменений! ... */

Теперь при просмотре state из GDB мы видим что-то полезное:

(gdb) print state

$1 = NOSTATE

15.4.1.3. При необходимости переставляйте код

Довольно часто условие в

if
или
while
состоит из нескольких проверок, разделенных
&&
или
||
. Если эти проверки являются вызовами функций (или даже не являются ими), невозможно осуществить пошаговое прохождение каждой отдельной части условия. Команды GDB
step
и
next
работают на основе операторов (statements), а не выражений (expressions). (Разнесение их по нескольким строкам все равно не помогает).

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

Вот конкретный пример: функция

do_input
из файла
io.c gawk
:

1 /* do_input --- главный цикл обработки ввода */

2

3 void

4 do_input

5 {

6 IOBUF *iop;

7 extern int exiting;

8 int rval1, rval2, rval3;

9

10 (void)setjmp(filebuf); /* for 'nextfile' */

11

12 while ((iop = nextfile(FALSE)) != NULL) {

13 /*

14 * Здесь было:

15 if (inrec(iop) == 0)

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец