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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π² LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 122

Автор НСйл ΠœΡΡ‚ΡŒΡŽ

Π”Π°Π»Π΅Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π²Ρ‹Π²ΠΎΠ΄Π°, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ вСрсиСй cflow (cflow-2.0), которая Π΅ΡΡ‚ΡŒ Π² Π˜Π½Ρ‚Π΅Ρ€Π½Π΅Ρ‚Π΅ ΠΈ поддСрТиваСтся ΠœΠ°Ρ€Ρ‚ΠΈ ЛСйснСром (Marty Leisner).

0  file_ungetc {prcc.c 997}

1  main {prcc.c 70}

2      getopt {}

3      show_all_lists {prcc.c 1070}

4          display_list {prcc.c 1056}

5              printf {}

6          exit {}

7      exit {}

9      usage {prcc.c 59}

10         fprintf {}

11         exit {}

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ функция main Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ (срСди ΠΏΡ€ΠΎΡ‡ΠΈΡ…) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ show_all_lists ΠΈ Ρ‡Ρ‚ΠΎ show_all_lists Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ display_list, которая Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ printf.

Π£ этой вСрсии cflow Π΅ΡΡ‚ΡŒ опция -i, которая Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΈΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Π³Ρ€Π°Ρ„. Π£Ρ‚ΠΈΠ»ΠΈΡ‚Π° cflow пСрСчисляСт для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Π΄Π°Π½Π½ΡƒΡŽ. Π—Π²ΡƒΡ‡ΠΈΡ‚ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ понятно, Π½ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ всС просто. Π”Π°Π»Π΅Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

19  display_list {prcc.c 1056}

20      show_all_lists {prcc.c 1070}

21  exit {}

22      main {prcc.c 70}

23      show_all_lists {prcc.c 1070}

24      usage {prcc.c 59}

25  ...

74  printf {}

75      display_list {prcc.c 1056}

76      maketag {prcc.c 4 87}

77  show_all_lists {prcc.c 1070}

78      main {prcc.c 70}

79  ...

99  usage {prcc.c 59}

100     main {prcc.c 70}

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, Ρ‡Ρ‚ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ exit, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main, show_all_lists ΠΈ usage.

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ профилирования с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ prof/gprof

ΠœΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ°, Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ полСзная ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ°Ρ… Π²Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ сниТСния ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, называСтся ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ выполнСния (execution profiling). ΠŸΡ€ΠΎΡ„ΠΈΠ»ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ опциями компилятора ΠΈ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Π³Π΄Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ‚Ρ€Π°Ρ‚ΠΈΡ‚ врСмя.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° prof (ΠΈ Π΅Π΅ эквивалСнт Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ GNU, gprof) Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚Ρ‡Ρ‘Ρ‚ ΠΈΠ· Ρ„Π°ΠΉΠ»Π° трассировки выполнСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ формируСтся Π²ΠΎ врСмя выполнСния ΠΏΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠŸΡ€ΠΎΡ„ΠΈΠ»ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ исполняСмый Ρ„Π°ΠΉΠ» создаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„Π»Π°Π³Π° компилятора -p (для prof) ΠΈΠ»ΠΈ Ρ„Π»Π°Π³Π° -pg (для gprof).

$ cc -pg -о program program.с

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° компонуСтся со ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ Π‘, ΠΈ Π² Π½Π΅Π΅ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄. Π’ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… систСмах ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚Π»ΠΈΡ‡Π°Ρ‚ΡŒΡΡ, Π½ΠΎ общая Ρ†Π΅Π»ΡŒ β€” такая организация ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, которая позволяСт часто ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΈ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ этап выполнСния. ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Π·Π°ΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Ρ„Π°ΠΉΠ» mon.out (gmon.out для gprof) Π² Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅.

$ ./program

$ ls -ls

2 -rw-r--r-- 1 neil users 1294 Feb 4 11:48 gmon.out

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° prof/gprof Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ эти ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚Ρ‡Π΅Ρ‚. Π‘ΠΌ. подробности, ΠΊΠ°ΡΠ°ΡŽΡ‰ΠΈΠ΅ΡΡ ΠΎΠΏΡ†ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌ справочном руководствС. Π”Π°Π»Π΅Π΅ Π² качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π²Ρ‹Π²ΠΎΠ΄ (сокращСнный) ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ gprof.

cumulative  self    self   total

   time    seconds seconds  calls ms/call ms/call            name

   18.5       0.10    0.10   8664    0.01    0.03      doscan [4]

   18.5       0.20    0.10                            mcount (60)

   14.8       0.28    0.08  43320    0.00    0.00     _number [5]

    9.3       0.33    0.05   8664    0.01    0.01 _format_arg [6]

    7.4       0.37    0.04 112632    0.00    0.00     _ungetc [8]

    7.4       0.41    0.04   8757    0.00    0.00    _memccpy [9]

    7.4       0.45    0.04      1   40.00  390.02       _main [2]

    3.7       0.47    0.02     53    0.38    0.38      _read [12]

    3.7       0.49    0.02                             w4str [10]

    1.9       0.50    0.01  26034    0.00    0.00    _strlen [16]

    1.9       0.51    0.01   8664    0.00    0.00    strncmp [17]

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ соблюдСния условий

НСсмотря Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ вставка Π½Π° этапС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ условной компиляции ΠΎΡ‚Π»Π°Π΄ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π²Ρ‹Π·ΠΎΠ²Ρ‹ printf, распространСна, ΠΈΠ½ΠΎΠ³Π΄Π° ΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ сообщСния Π² поставляСмой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π΅ΠΏΡ€Π°ΠΊΡ‚ΠΈΡ‡Π½ΠΎ. Но часто ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ Π²ΠΎ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ·-Π·Π° Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… Π΄ΠΎΠΏΡƒΡ‰Π΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ исходных Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π½Π΅ ΠΈΠ·-Π·Π° ошибок кодирования. Π­Ρ‚ΠΎ события, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… "Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½ΠΈΠΊΠΎΠ³Π΄Π°". НапримСр, функция ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ написана Π² расчСтС Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π΅Π΅ Π²Ρ…ΠΎΠ΄Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅. Если ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅ΠΉ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Ρƒ всСй систСмы.

Π’ Ρ‚Π΅Ρ… случаях, ΠΊΠΎΠ³Π΄Π° внутрСнняя Π»ΠΎΠ³ΠΈΠΊΠ° систСмы нуТдаСтся Π² ΠΏΠΎΠ΄ΠΊΡ€Π΅ΠΏΠ»Π΅Π½ΠΈΠΈ, X/Open прСдоставляСт макрос assert, примСняСмый для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΡΡ‚ΠΈ исходных Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ остановки выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС.

#include <assert.h>

void assert(int expression)

ΠœΠ°ΠΊΡ€ΠΎΡ assert вычисляСт Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈ, Ссли ΠΎΠ½ΠΎ Π½Π΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π΄ΠΈΠ°Π³Π½ΠΎΡΡ‚ΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ стандартной ошибкС ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ abort для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» assert.h опрСдСляСт макросы Π² зависимости ΠΎΡ‚ опрСдСлСния Ρ„Π»Π°Π³Π° NDEBUG. Если NDEBUG ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ Π²ΠΎ врСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°, assert опрСдСляСтся ΠΏΠΎ сущСству ΠΊΠ°ΠΊ Π½ΠΈΡ‡Ρ‚ΠΎ. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π·Π°Π΄Π°Π½Π½Ρ‹Ρ… Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π²ΠΎ врСмя компиляции, компилируя с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ -DNDEBUG ΠΈΠ»ΠΈ вставив ΠΏΠ΅Ρ€Π΅Π΄ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ„Π°ΠΉΠ»Π° assert.h строку

#define NDEBUG

Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ исходный Ρ„Π°ΠΉΠ».

Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ примСнСния ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ. Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ assert Π²ΠΎ врСмя тСстирования, Π½ΠΎ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ макрос Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΊΠΎΠ΄Π΅, Π² вашСм Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΊΠΎΠ΄Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΌΠ΅Π½Π΅Π΅ строгая ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΠ²ΡˆΠ°ΡΡΡ Π² процСссС Π΅Π³ΠΎ тСстирования. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ макросы assert Π½Π΅ ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΊΠΎΠ΄Π΅ β€” вряд Π»ΠΈ Π²Π°ΠΌ понравится Ρ€Π°Π±ΠΎΡ‡ΠΈΠΉ ΠΊΠΎΠ΄, ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π½Π΅Π΄Ρ€ΡƒΠΆΠ΅Π»ΡŽΠ±Π½ΠΎΠ΅ сообщСниС assert failed ΠΈ ΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π‘Ρ‹Ρ‚ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚, Π»ΡƒΡ‡ΡˆΠ΅ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ свою ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΡŽΡ‰ΡƒΡŽ ошибки ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, которая провСряСт Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, использовавшССся Π² макросС, Π½ΠΎ Π½Π΅ нуТдаСтся Π² ΠΏΠΎΠ»Π½ΠΎΠΌ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΊΠΎΠ΄Π΅.

Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ выраТСния макроса assert Π½Π΅Ρ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов. НапримСр, Ссли Π²Ρ‹ примСняСтС Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΌ эффСктом, этот ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹ΠΉ эффСкт Π½Π΅ проявится Π² Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΊΠΎΠ΄Π΅ с ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ макросами assert.

Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 10.2.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 10.2. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° assert.c.

Π”Π°Π»Π΅Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° assert.c, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰Π°Ρ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, которая Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Она Π·Π°Ρ‰ΠΈΡ‰Π°Π΅Ρ‚ ΠΎΡ‚ Π²Π²ΠΎΠ΄Π° Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° благодаря ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡŽ макроса assert.

ПослС Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° assert.h ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ "ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π½Ρ‹ΠΉ ΠΊΠΎΡ€Π΅Π½ΡŒ", ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡŽΡ‰Π΅ΠΉ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ main.

#include <stdio.h>

#include <math.h>

#include <assert.h>

#include <stdlib.h>


double my_sqrt(double x) {

 assert(x >= 0.0);

 return sqrt(x);

}


int main() {

 printf("sqrt +2 = %g\n", my_sqrt(2.0));

 printf("sqrt -2 = %g\n", my_sqrt(-2.0));

 exit(0);

}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ Π² макросС assert ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ значСния. Π’ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ сообщСния ΠΎ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΈ условия макроса assert Π² Ρ€Π°Π·Π½Ρ‹Ρ… систСмах Ρ€Π°Π·Π½Ρ‹ΠΉ.

$ сс -о assert assert.с -lm

$ ./assert

sqrt +2 = 1.41421

assert: assert.c:7: my_sqrt: Assertion 'x >= 0.0' failed.

Aborted

$

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

Когда Π²Ρ‹ ΠΏΠΎΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ my_sqrt с ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ числом, макрос assert даст сбой. Он прСдоставляСт Ρ„Π°ΠΉΠ» ΠΈ Π½ΠΎΠΌΠ΅Ρ€ строки, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΎ условиС ΠΈ само Π½Π°Ρ€ΡƒΡˆΠ΅Π½Π½ΠΎΠ΅ условиС. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠ΅ΠΌ abort. Π­Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π²Ρ‹Π·ΠΎΠ²Π° abort макросом assert.

Если Π²Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ -DNDEBUG, макрос assert Π½Π΅ компилируСтся, ΠΈ Π²Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚Π΅ NaN (Not a Number, Π½Π΅ число) β€” Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π΅ Π½Π° Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sqrt ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_sqrt.

$ cc -о assert -DNDEBUG assert.с -lm

$ ./assert

sqrt +2 = 1.41421

sqrt -2 = nan

$

НСкоторыС Π±ΠΎΠ»Π΅Π΅ старыС вСрсии матСматичСской Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ для матСматичСской ошибки, ΠΈ ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ остановлСна с сообщСниСм "Floating point exception" ("Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ для числа с ΠΏΠ»Π°Π²Π°ΡŽΡ‰Π΅ΠΉ Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ") вмСсто Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° NaN.

УстранСниС ошибок использования памяти

РаспрСдСлСниС динамичСской памяти β€” Π±ΠΎΠ³Π°Ρ‚Ρ‹ΠΉ источник ошибок, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ. Если Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡŽΡ‰ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ malloc ΠΈ free для распрСдСлСния памяти, Π²Π°ΠΆΠ½ΠΎ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Π±Π»ΠΎΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ выдСляСтС, ΠΈ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π±Π»ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹ ΡƒΠΆΠ΅ освободили.

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π±Π»ΠΎΠΊΠΈ памяти Π²Ρ‹Π΄Π΅Π»ΡΡŽΡ‚ΡΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ malloc ΠΈ ΠΏΡ€ΠΈΡΠ²Π°ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ-указатСлям. Если пСрСмСнная-ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ измСняСтся, ΠΈ Π½Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… Π½Π° Π±Π»ΠΎΠΊ памяти, ΠΎΠ½ становится нСдоступным. Π­Ρ‚ΠΎ ΡƒΡ‚Π΅Ρ‡ΠΊΠ° памяти, Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π°Ρ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Если Π²Ρ‹ потСряСтС большой объСм памяти, ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ вашСй систСмы, Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², снизится, ΠΈ систСма ΡƒΠΉΠ΄Π΅Ρ‚ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ памяти.