Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Linux ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 140

Автор ΠΡ€Π½ΠΎΠ»ΡŒΠ΄ Роббинс

ВывСсти содСрТимоС памяти ΠΌΠΎΠΆΠ½ΠΎ с использованиСм ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ print. GDB распознаСт синтаксис Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π‘, Ρ‡Ρ‚ΠΎ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ ΠΈ Π΄Π΅Π»Π°Π΅Ρ‚ СстСствСнным ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ структур, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΡΡ‹Π»Π°ΡŽΡ‚ΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ:

(gdb) print *save /* ВывСсти структуру, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ save */

$1 = {sub = {nodep = {l = {lptr = 0x8095250, param_name = 0x8095250 "pR\t\b",

 l1 = 134828624}, r = {rptr = 0x0, pptr = 0, preg = 0x0,

 hd = 0x0, av = 0x0, r_ent =0}, x = {extra = 0x0, x1 = 0,

 param_list = 0x0},

 name = 0x0, number = 1, reflags = 0}, val = {

 fltnum = 6.6614191194446594e-316, sp = 0x0, slen = 0, sref = 1,

 idx = 0}, hash = {next = 0x8095250, name = 0x0, length = 0, value = 0x0,

 ref = 1}}, type = Node_expression_list, flags = 1}

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΠΌΠ°Π½Π΄Π° cont (continue β€” ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ) Π΄Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Она Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π΄ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΈΠ»ΠΈ Π΄ΠΎ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, Ссли Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Ρ… Ρ‚ΠΎΡ‡Π΅ΠΊ Π½Π΅Ρ‚. Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ продолТаСтся с Ρ‚ΠΎΠ³ΠΎ мСста, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ остановился ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ:

1520 for (numnodes = 0; tree != NULL; tree = tree->rnode)

(gdb) cont /* ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ *!

Continuing.

hello, world


Program exited normally. /* Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΡ‚ GDB */

(gdb) quit /* Π’Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· ΠΎΡ‚Π»Π°Π΄Ρ‡ΠΈΠΊΠ° */

ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΠ°Ρ Ρ‚ΠΎΡ‡ΠΊΠ° (watchpoint) ΠΏΠΎΠ΄ΠΎΠ±Π½Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠ΅, Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π½Π΅ для ΠΊΠΎΠ΄Π°. ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ (ΠΈΠ»ΠΈ поля структуры ΠΈΠ»ΠΈ объСдинСния ΠΈΠ»ΠΈ элСмСнта массива), ΠΏΡ€ΠΈ ΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ GDB посылаСт увСдомлСния. GDB провСряСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ отслСТиваСмой Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΏΠΎ ΠΌΠ΅Ρ€Π΅ пошагового исполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ останавливаСтся ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ значСния. НапримСр, пСрСмСнная do_lint_old Π² gawk Ρ€Π°Π²Π½Π° true, ΠΊΠΎΠ³Π΄Π° Π±Ρ‹Π»Π° использована опция --lint_old. Π­Ρ‚Π° пСрСмСнная устанавливаСтся Π² true Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ getopt_long(). (ΠœΡ‹ рассмотрСли getopt_long() Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 2.1.2 Β«Π”Π»ΠΈΠ½Π½Ρ‹Π΅ ΠΎΠΏΡ†ΠΈΠΈ GNUΒ»). Π’ Ρ„Π°ΠΉΠ»Π΅ main.c ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ gawk:

int do_lint_old = FALSE;

 /* ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΡ‚ΡŒ ΠΎ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π΅, Π½Π΅ имСвшСйся Π² V7 awk */

...

static const struct option optab[] = {

 ...

 { "lint-old", no_argument, &do_lint_old, 1 },

 ...

};

Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ сСанса, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ Π² дСйствии:

$ gdb gawk /* Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ GDB с gawk */

GNU gdb 5.3

...

(gdb) watch do_lint_old

 /* Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΡƒΡŽ Ρ‚ΠΎΡ‡ΠΊΡƒ для ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ */

Hardware watchpoint 1: do_lint_old

(gdb) run --lint-old 'BEGIN { print "hello, world" }'

 /* Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ */

Starting program: /home/arnold/Gnu/gawk/gawk-3.1.4/gawk β€”lint-old

'BEGIN { print "hello, world" }'

Hardware watchpoint 1: do_lint_old

Hardware watchpoint 1: do_lint_old

Hardware watchpoint 1: do_lint_old

 /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° отслСТиваСмой Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ */

Hardware watchpoint 1: do_lint_old

Hardware watchpoint 1: do_lint_old

Old value = 0 /* ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π΅ΠΌΠ°Ρ Ρ‚ΠΎΡ‡ΠΊΠ° останавливаСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ */

New value = 1

0x420c4219 in _getopt_internal() from /lib/i686/libc.so.6

(gdb) where /* Врассировка стСка */

#0 0x420c4219 in _getopt_internal() from /lib/i686/libc.so.6

#1 0x420c4e83 in getopt_long() from /lib/i686/libc.so.6

#2 0x080683a1 in main (argc=3, argv=0xbffff8a4) at main.c:293

#3 0x420158d4 in __libc_start_main() from /lib/i686/libc.so.6

(gdb) quit /* На Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΌΡ‹ Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΈ */

The program is running. Exit anyway? (y or n) y /* Π”Π° */

GDB ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π΅Π»Π°Ρ‚ΡŒ Π³ΠΎΡ€Π°Π·Π΄ΠΎ большС, Ρ‡Π΅ΠΌ ΠΌΡ‹ здСсь ΠΏΠΎΠΊΠ°Π·Π°Π»ΠΈ. Π₯отя руководство GDB большоС, Π΅Π³ΠΎ стоит ΠΏΡ€ΠΎΡ‡Π΅ΡΡ‚ΡŒ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ хотя Π±Ρ‹ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡ‚ΡŒΡΡ с Π΅Π³ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ ΠΈ возмоТностями. ПослС этого, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π±ΡƒΠ΄Π΅Ρ‚ достаточно ΠΏΡ€ΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ„Π°ΠΉΠ» NEWS Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ Π½ΠΎΠ²ΠΎΠΌ дистрибутивС GDB, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Ρ‡Ρ‚ΠΎ измСнилось.

Π‘Ρ‚ΠΎΠΈΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π°ΡΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ ΡΠΏΡ€Π°Π²ΠΎΡ‡Π½ΡƒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΡƒ GDB, которая поставляСтся Π² дистрибутивС GDB Π² Ρ„Π°ΠΉΠ»Π΅ gdb/doc/refcard.tex. Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΏΠ΅Ρ‡Π°Ρ‚Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ справочной ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠΈ для PostScript послС извлСчСния исходника ΠΈ запуска configure ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΊΠΎΠΌΠ°Π½Π΄:

$ cd gdb/doc /* ΠŸΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΎ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ doc */

$ make refcard.ps /* ΠžΡ‚Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΏΡ€Π°Π²ΠΎΡ‡Π½ΡƒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΡƒ */

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚ΡΡ, Ρ‡Ρ‚ΠΎ справочная ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ распСчатана с Π΄Π²ΡƒΡ… сторон листа Π±ΡƒΠΌΠ°Π³ΠΈ 8,5Γ—11 дюймов[168] (Ρ€Π°Π·ΠΌΠ΅Ρ€ Β«letterΒ») Π² Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΌ (landscape) Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅. Π’ Π½Π΅ΠΉ Π½Π° ΡˆΠ΅ΡΡ‚ΠΈ ΠΊΠΎΠ»ΠΎΠ½ΠΊΠ°Ρ… прСдоставлСна сводка Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ GDB. ΠœΡ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ Ρ€Π°ΡΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ Π΅Π΅ ΠΈ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠΎΠ΄ своСй ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€ΠΎΠΉ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с GDB.

15.4. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ мноТСство ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊ для упрощСния ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ исходного ΠΊΠΎΠ΄Π°, ΠΎΡ‚ простых Π΄ΠΎ слоТных. Π’ Π΄Π°Π½Π½ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ рассмотрим ряд ΠΈΠ· Π½ΠΈΡ….

15.4.1. Код ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ компилирования

НСсколько ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊ относятся ΠΊ самому исходному ΠΊΠΎΠ΄Ρƒ.

15.4.1.1. ИспользованиС ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½Ρ‹Ρ… макросов

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠΎΠΉ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ компилирования являСтся использованиС прСпроцСссора для создания условно ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. НапримСр:

#ifdef DEBUG

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

fflush(stderr);

#endif /* DEBUG */

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ -DDEBUG ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС компилятора Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ fprintf() ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

РСкомСндация: сообщСния ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ посылайтС Π² stderr, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ Π½Π΅ Π±Ρ‹Π»ΠΈ потСряны Π² ΠΊΠ°Π½Π°Π»Π΅ ΠΈ Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡ… ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ пСрСнаправлСния Π²Π²ΠΎΠ΄Π°/Π²Ρ‹Π²ΠΎΠ΄Π°. Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ использовали fflush(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ сообщСния Π±Ρ‹Π»ΠΈ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ скорСС

Π—ΠΠœΠ•Π§ΠΠΠ˜Π•. Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ DEBUG, хотя ΠΎΠ½ ΠΈ ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹ΠΉ, Ρ‚Π°ΠΊΠΆΠ΅ часто злоупотрСбляСтся. Π›ΡƒΡ‡ΡˆΠ΅ΠΉ ΠΌΡ‹ΡΠ»ΡŒΡŽ являСтся использованиС спСцифичСского для вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°, Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ°ΠΊ MYAPPDEBUG. МоТно Π΄Π°ΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΊΠΎΠ΄Π° Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… частях ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ‚Π°ΠΊΠΈΡ…, ΠΊΠ°ΠΊ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ Π²Π²ΠΎΠ΄/Π²Ρ‹Π²ΠΎΠ΄, вСрификация Π΄Π°Π½Π½Ρ‹Ρ…, ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ ΠΈ Ρ‚.Π΄.

РазбрасываниС Π±ΠΎΠ»ΡŒΡˆΠΈΡ… количСств ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² #ifdef ΠΏΠΎ всСму ΠΊΠΎΠ΄Ρƒ быстро становится ΡƒΡ‚ΠΎΠΌΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ. Π‘ΠΎΠ»ΡŒΡˆΠΎΠ΅ количСство #ifdef ΡΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π”ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π»ΡƒΡ‡ΡˆΠΈΠΉ способ, ΠΈ Π² самом Π΄Π΅Π»Π΅, часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ° с условным ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ макроса для Π²Ρ‹Π²ΠΎΠ΄Π°:

/* ΠœΠ•Π’ΠžΠ”Π˜ΠšΠ 1 --- ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠ°Ρ, Π½ΠΎ Π½Π΅ рСкомСндуСмая, см. тСкст */

/* Π’ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ прилоТСния: */ #ifdef MYAPPDEBUG

#define DPRINT0(msg) fprintf(stderr, msg)

#define DPRINT1(msg, v1) fprintf(stderr, msg, v1)

#define DPRINT2(msg, v1, v2) fprintf(stderr, msg, v1, v2)

#define DPRINT3(msg, v1, v2, v3) fprintf(stderr, msg, v1, v2, v3)

#else /* ! MYAPPDEBUG */

#define DPRINT0(msg)

#define DPRINT1(msg, v1)

#define DPRINT2(msg, v1, v2)

#define DPRINT3(msg, v1, v2, v3)

#endif /* ! MYAPPDEBUG */


/* Π’ исходном Ρ„Π°ΠΉΠ»Π΅ прилоТСния: */

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

...

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

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ нСсколько макросов, ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π½Π° ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΉΡΡ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, число ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… опрСдСляСтС Π²Ρ‹ сами. Когда ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ MYAPPDEBUG, Π²Ρ‹Π·ΠΎΠ²Ρ‹ макросов DPRINTx() Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π²Ρ‹Π·ΠΎΠ²Ρ‹ fprintf(). Когда MYAPPDEBUG Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½, эти Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π½ΠΈΡ‡Ρ‚ΠΎ. (Π’Π°ΠΊ, Π² сущности, Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ assert(); ΠΌΡ‹ описали assert() Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 12.1 Β«ΠžΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ: assert()Β».)

Π­Ρ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚; ΠΌΡ‹ сами Π΅Π΅ использовали ΠΈ Π²ΠΈΠ΄Π΅Π»ΠΈ, ΠΊΠ°ΠΊ Π΅Π΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽΡ‚ Π² ΡƒΡ‡Π΅Π±Π½ΠΈΠΊΠ°Ρ…. Однако, ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½ΡΡ‚Π²ΠΎΠ²Π°Π½Π° ΠΈ дальшС с ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠ΅ΠΌ количСства макросов Π΄ΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ:

/* ΠœΠ•Π’ΠžΠ”Π˜ΠšΠ 2 --- Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ пСрСносима; рСкомСндуСтся */

/* Π’ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ прилоТСния: */

#ifdef MYAPPDEBUG

#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__ замСщаСтся прСдусмотрСнными Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ, сколько Π±Ρ‹ ΠΈΡ… Π½ΠΈ Π±Ρ‹Π»ΠΎ.