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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «Освой ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π‘++ Π·Π° 21 дСнь.Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 147

Автор ДТСсс Π›ΠΈΠ±Π΅Ρ€Ρ‚ΠΈ

#define Listof(Type) class Type##List

{

   public:

      Type##List(){ }

   private:

      int itsLength;

};

Π‘ΡƒΡ‚ΡŒ этого ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π² ΠΎΠ΄Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ всС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΈ Π΄Π°Π½Π½Ρ‹Π΅. Когда Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ список ΠΆΠΈΠ²ΠΎΡ‚Π½Ρ‹Ρ… (AnimalList), достаточно Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ

Listof(Animal)

ΠΈ привСдСнная Π²Ρ‹ΡˆΠ΅ запись прСвратится Π² объявлСниС класса AnimalList. Π’ процСссС примСнСния этого ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° Π½Π΅ обходится Π±Π΅Π· Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассмотрСнных Π½Π° занятии 19.

ВстроСнныС макросы

МногиС компиляторы ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ряд встроСнных макросов, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ DATE, __TIME__, __LINE__ ΠΈ __FILE__ . КаТдоС ΠΈΠ· этих ΠΈΠΌΠ΅Π½ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΎ двумя символами подчСркивания, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ Π²Π΅Ρ€ΠΎΡΡ‚Π½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π²ΠΎΠΉΠ΄ΡƒΡ‚ Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡ΠΈΠ΅ с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Π½Ρ‹ΠΌΠΈ Π² вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅.

Когда прСпроцСссор встрСчаСт ΠΎΠ΄ΠΈΠ½ ΠΈΠ· этих макросов, ΠΎΠ½ Π΄Π΅Π»Π°Π΅Ρ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΡƒΡŽ подстановку. ВмСсто лСксСмы __DATE__ ставится тСкущая Π΄Π°Ρ‚Π°. ВмСсто __TIME__ β€” Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя. ЛСксСмы __LINE__ ΠΈ __FILE__ Π·Π°ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ строки исходного ΠΊΠΎΠ΄Π° ΠΈ ΠΈΠΌΠ΅Π½Π΅ΠΌ Ρ„Π°ΠΉΠ»Π° соотвСтствСнно. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ эти Π·Π°ΠΌΠ΅Π½Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π΅Ρ‰Π΅ Π΄ΠΎ компиляции. Π£Ρ‡Ρ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ вмСсто лСксСмы DATE Π±ΡƒΠ΄Π΅Ρ‚ ΡΡ‚ΠΎΡΡ‚ΡŒ Π½Π΅ тСкущая Π΄Π°Ρ‚Π°, Π° Π΄Π°Ρ‚Π° компиляции ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ВстроСнныС макросы часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅.

ΠœΠ°ΠΊΡ€ΠΎΡ assert()

Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… компиляторах прСдусмотрСн макрос assert, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ TRUE, Ссли Π΅Π³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ TRUE, ΠΈ выполняСт установлСнныС дСйствия, Ссли Π΅Π³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ FALSE. МногиС компиляторы Π² этом случаС ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°ΡŽΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΆΠ΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ (см. занятиС 20).

Одна ΠΈΠ· Π²Π°ΠΆΠ½Ρ‹Ρ… особСнностСй макроса assert() состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ прСпроцСссор Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Π·Π°ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ, Ссли Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° лСксСма DEBUG. Π­Ρ‚ΠΎ свойство β€” большоС ΠΏΠΎΠ΄ΡΠΏΠΎΡ€ΡŒΠ΅ Π² ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΡƒ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Π°. БыстродСйствиС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π΅ страдаСт ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ исполняСмой вСрсии Π½Π΅ увСличиваСтся Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ использования этого макроса.

Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ Π·Π°Π²ΠΈΡΠ΅Ρ‚ΡŒ ΠΎΡ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ вСрсии компилятора, Ρ‚.Π΅. ΠΎΡ‚ Π΅Π³ΠΎ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ Π½Π° макрос assert(), ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ собствСнный Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ этого макроса. Π’ листингС 21.4 содСрТится простой макрос assert() ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π΅Π³ΠΎ использованиС.

Листинг 21.4. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ макрос assert() 

1: // Листинг 21.4. ΠœΠ°ΠΊΡ€ΠΎΡ ASSERT

2: #define DEBUG

3: #include <iostream.h>

4:

5: #ifndef DEBUG

6:    #define ASSERT(x)

7: #else

8:    #define ASSERT(x)

9:    if (! (x))

10:   {

11:      cout << "ERROR!! Assert " << #x << " failed\n"; \

12:      cout << " on line " << __LINE__ << "\n"; \

13:      cout << " in file " <<  FILE  << "\n"; \

14:   }

15: #endif

16:

17:

18: int main()

19: {

20:    int x = 5;

21:    cout << "ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ макрос assert: \n";

22:    ASSERT(x==5);

23:    cout << "\nΠ’Ρ‚ΠΎΡ€ΠΎΠΉ макрос assert: \n";

24:    ASSERT(x != 5);

25:    cout << "\nΠ’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎΠ” n";

26:    return 0:

27: }


Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

First assert:

Second assert:

ERROR!! Assert x !=5 failed

on line 24

in file test1704.cpp

Done.


Анализ: Π’ строкС 2 опрСдСляСтся лСксСма DEBUG. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ это дСлаСтся ΠΈΠ· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки (ΠΈΠ»ΠΈ Π² ΠΈΠ½Ρ‚Π΅Π³Ρ€ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ срСдС Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ) Π²ΠΎ врСмя компиляции, Ρ‡Ρ‚ΠΎ позволяСт ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ этим процСссом. Π’ строках 8-14 опрСдСляСтся макрос assert(). Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, это дСлаСтся Π² Ρ„Π°ΠΉΠ»Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ASSERT.hpp, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ слСдуСт Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π²ΠΎ всС Ρ„Π°ΠΉΠ»Ρ‹ источников.

Π’ строкС 5 провСряСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ лСксСмы DEBUG. Если ΠΎΠ½Π° Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°, макрос assert() опрСдСляСтся Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ создавался Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΊΠΎΠ΄. Если ΠΆΠ΅ лСксСма DEBUG ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°, Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ строки ΠΊΠΎΠ΄Π° 8-14.

Π‘Π°ΠΌ макрос assert() прСдставляСт собой Ρ†Π΅Π»ΡŒΠ½ΠΎΠ΅ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, Ρ€Π°Π·Π±ΠΈΡ‚ΠΎΠ΅ Π½Π° сСмь строк исходного ΠΊΠΎΠ΄Π°. Π’ строкС 9 провСряСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΠΎΠ΅ ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€. Если ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ FALSE, выводится сообщСниС ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… (строки 11 β€” 13). Если ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ TRUE, Π½ΠΈΠΊΠ°ΠΊΠΈΠ΅ дСйствия Π½Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ.

Оладка ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ assert()

МногиС ошибки Π΄ΠΎΠΏΡƒΡΠΊΠ°ΡŽΡ‚ΡΡ программистами, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ вСрят Π² Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π±ΡƒΠ΄Π΅Ρ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это логичСски ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, ΠΈ Π·Π°Π±Ρ‹Π²Π°ΡŽΡ‚ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ компилятор Π½Π΅ подчиняСтся чСловСчСской Π»ΠΎΠ³ΠΈΠΊΠ΅, Π° слСпо слСдуСт ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌ ΠΈ инструкциям, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΡ€Π΅Ρ‡Π°Ρ‚ всякой Π»ΠΎΠ³ΠΈΠΊΠ΅. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ самым нСпонятным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π·Π°Π±Ρ‹Π»ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΏΡ€ΠΈ объявлСнии, ΠΈ поэтому ΠΎΠ½ ссылаСтся Π½Π° случайныС Π΄Π°Π½Π½Ρ‹Π΅, ΡΠΎΡ…Ρ€Π°Π½ΠΈΠ²ΡˆΠΈΠ΅ΡΡ Π² связанных с Π½ΠΈΠΌ ячСйках памяти. ΠœΠ°ΠΊΡ€ΠΎΡ assert() ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ Π² поискС ошибок Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΠΏΡ€ΠΈ условии, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π½Π°ΡƒΡ‡ΠΈΡ‚Π΅ΡΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ этот макрос Π² своих ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ пСрСдаСтся ΠΊΠ°ΠΊ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΈΠ»ΠΈ Π² Π²ΠΈΠ΄Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π»ΠΈ этот ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ссылаСтся Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’ любом мСстС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ссли Π΅Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ зависит ΠΎΡ‚ значСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ макроса assert() Π²Ρ‹ смоТСтС ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π½Π° это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ.

ΠŸΡ€ΠΈ этом ΠΎΡ‚ частого использования макроса assert() Π²Ρ‹ Π½Π΅ нСсСтС Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΡƒΠ±Ρ‹Ρ‚ΠΊΠΎΠ², ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ автоматичСски удаляСтся ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ссли Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° лСксСма DEBUG. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, присутствиС макроса assert() Ρ‚Π°ΠΊΠΆΠ΅ обСспСчиваСт Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π΅ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ надСляСт Π² ΠΊΠΎΠ΄Π΅ Π²Π°ΠΆΠ½Ρ‹Π΅ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ слСдуСт ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π² случаС ΠΌΠΎΠ΄Π΅Ρ€Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

ΠœΠ°ΠΊΡ€ΠΎΡ assert() вмСсто ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ

На ΠΏΡ€ΠΎΡˆΠ»ΠΎΠΌ занятии Π²Ρ‹ ΡƒΠ·Π½Π°Π»ΠΈ, ΠΊΠ°ΠΊ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΈ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ Π°Π²Π°Ρ€ΠΈΠΉΠ½Ρ‹Π΅ ситуации. Π’Π°ΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ макрос assert() Π½Π΅ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Ρ‚Π°ΠΊΠΈΡ… ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ситуаций, ΠΊΠ°ΠΊ Π²Π²ΠΎΠ΄ ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠ° памяти, Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈ Ρ‚.Π΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ Π²ΠΎ врСмя выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. ΠœΠ°ΠΊΡ€ΠΎΡ assert() создан для отслСТивания логичСских ΠΈ синтаксичСских ошибок программирования. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ссли макрос assert() срабатываСт, это сигнализируСт ΠΎΠ± ошибкС нСпосрСдствСнно Π² ΠΊΠΎΠ΄Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΠ°ΠΌ макросы assert() Π² ΠΊΠΎΠ΄Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΠ΄Π°Π»Π΅Π½Ρ‹. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Ссли с ошибками выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΡƒΠ΄Π°Π²Π°Π»ΠΎΡΡŒ ΡΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ благодаря макросу assert(), Ρ‚ΠΎ Ρƒ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΠ° эта ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° просто Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ.

РаспространСнной ошибкой являСтся использованиС макроса assert() для тСстирования Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния ΠΏΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ выдСлСния памяти:

Animal *pCat = new Cat:

Assert(pCat); // Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ использованиС макроса pCat->SomeFunction();

Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ классичСской ошибки ΠΏΡ€ΠΈ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС программист пытаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ макроса assert() ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΡ‚ΡŒ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ситуации Π½Π΅Ρ…Π²Π°Ρ‚ΠΊΠΈ свободной памяти. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ программист тСстируСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π° ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅ с достаточным объСмом памяти, поэтому макрос assert()B этом мСстС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ сработаСт. Π£ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡƒΡΡ‚Π°Ρ€Π΅Π²ΡˆΠ°Ρ вСрсия ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°, поэтому, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ Π΄ΠΎ этой Ρ‚ΠΎΡ‡ΠΊΠΈ, ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρƒ

new Ρ‚Π΅Ρ€ΠΏΠΈΡ‚ ΠΊΡ€Π°Ρ… ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ NULL (пустой ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ). Однако макроса assert() большС Π½Π΅Ρ‚ Π² ΠΊΠΎΠ΄Π΅, ΠΈ Π½Π΅ΠΊΠΎΠΌΡƒ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ссылаСтся Π½Π° NULL. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄ΠΎΠΉΠ΄Π΅Ρ‚ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π΄ΠΎ выраТСния pCat->SomeFunction(), ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄Π°Π΅Ρ‚ сбой.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ значСния NULL ΠΏΡ€ΠΈ выдСлСния памяти β€” это Π½Π΅ ошибка программирования, Π° ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ ситуация. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° смогла с Ρ‡Π΅ΡΡ‚ΡŒΡŽ Π²Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· этой ситуации, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. ΠŸΠΎΠΌΠ½ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ макрос assert() ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ удаляСтся ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ссли лСксСма DEBUG Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π°. (Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π±Ρ‹Π»ΠΈ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описаны Π½Π° занятии 20.)

ΠŸΠΎΠ±ΠΎΡ‡Π½Ρ‹Π΅ эффСкты

НСрСдко случаСтся Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ ошибка проявляСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС удалСния экзСмпляров макроса assert(). ΠŸΠΎΡ‡Ρ‚ΠΈ всСгда это происходит ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ ΠΏΠΎΠ±ΠΎΡ‡Π½Ρ‹Ρ… эффСктов, Π²Ρ‹Π·Π²Π°Π½Π½Ρ‹Ρ… Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ макроса assert() ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ частями ΠΊΠΎΠ΄Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ. НапримСр, Ссли Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ

ASSERT (x = 5)

ΠΏΡ€ΠΈ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ имСлась Π² Π²ΠΈΠ΄Ρƒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° x == 5, Π²Ρ‹ Ρ‚Π΅ΠΌ самым создадитС Ρ‡Ρ€Π΅Π·Π²Ρ‹Ρ‡Π°ΠΉΠ½ΠΎ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΡƒΡŽ ΠΎΡˆΠΈΠ±ΠΊΡƒ.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΊ Ρ€Π°Π· Π΄ΠΎ выполнСния макроса assert() Π²Ρ‹Π·Ρ‹Π²Π°Π»Π°ΡΡŒ функция, которая установила ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ x Ρ€Π°Π²Π½ΠΎΠΉ 0. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Π΄Π°Π½Π½Ρ‹ΠΉ макрос, Π²Ρ‹ ΠΏΠΎΠ»Π°Π³Π°Π»ΠΈ, Ρ‡Ρ‚ΠΎ выполняСтС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ равСнства ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ x Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ 5. На самом ΠΆΠ΅ Π΄Π΅Π»Π΅ Π²Ρ‹ устанавливаСтС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ x Ρ€Π°Π²Π½Ρ‹ΠΌ 5. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ эта лоТная ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ TRUE, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ x = 5 Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ устанавливаСт ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ x Ρ€Π°Π²Π½ΠΎΠΉ 5, Π½ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 5, Π° Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ 5 Π½Π΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, Ρ‚ΠΎ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ расцСниваСтся ΠΊΠ°ΠΊ истинноС.

Π’ΠΎ врСмя ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ макрос assert() Π½Π΅ выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ равСнства ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ x Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ 5, Π° присваиваСт Π΅ΠΉ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, поэтому ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ прСкрасно. Π’Ρ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅Π΅ Π·Π°ΠΊΠ°Π·Ρ‡ΠΈΠΊΡƒ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚Π΅ ΠΎΡ‚Π»Π°Π΄ΠΊΡƒ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ макрос assert() удаляСтся ΠΈΠ· ΠΊΠΎΠ΄Π° ΠΈ пСрСмСнная x Π½Π΅ устанавливаСтся Ρ€Π°Π²Π½ΠΎΠΉ 5. Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ошибки Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ пСрСмСнная x устанавливаСтся Ρ€Π°Π²Π½ΠΎΠΉ 0, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄Π°Π΅Ρ‚ сбой.