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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ программирования Π½Π° Π‘++. 101 ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ ΠΈ рСкомСндация». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 55

Автор Π“Π΅Ρ€Π± Π‘Π°Ρ‚Ρ‚Π΅Ρ€

[Dewhurst03] Β§50 β€’ [Stroustrup94] Β§11.4.4

97. НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ объСдинСния для ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠΉ

РСзюмС

Π₯ΠΈΡ‚Ρ€ΠΎΡΡ‚ΡŒ всС Ρ€Π°Π²Π½ΠΎ остаСтся лоТью: объСдинСния ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для получСния "прСобразования Ρ‚ΠΈΠΏΠ° Π±Π΅Π· прСобразования", записывая ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π² ΠΎΠ΄ΠΈΠ½ Ρ‡Π»Π΅Π½ ΠΈ считывая ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ. Однако это Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ опасно ΠΈ ΠΌΠ΅Π½Π΅Π΅ прСдсказуСмо, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ reinterpret_cast (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 92).

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

НС считывайтС Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· поля объСдинСния, Ссли послСдняя запись Π±Ρ‹Π»Π° Π½Π΅ Π² это ΠΆΠ΅ ΠΏΠΎΠ»Π΅. Π§Ρ‚Π΅Π½ΠΈΠ΅ ΠΈΠ· поля, ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΎΡ‚ поля, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠ»Π°ΡΡŒ запись, ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, ΠΈ использованиС этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π΅Ρ‰Π΅ Ρ…ΡƒΠΆΠ΅, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ reinterpret_cast (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 92); Π² послСднСм случаС компилятор, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅Π΄ΠΈΡ‚ΡŒ программиста ΠΈ Π½Π΅ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ "Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ" Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ указатСля Π² char. ΠŸΡ€ΠΈ использовании для этой Ρ†Π΅Π»ΠΈ объСдинСния никакая интСрпрСтация Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ошибкС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ компиляции (ΠΊΠ°ΠΊ ΠΈ ΠΊ Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠΌΡƒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρƒ).

Рассмотрим Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π°, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΠΎΠ³ΠΎ для сохранСния значСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° (char*) ΠΈ Π²Ρ‹Π±ΠΎΡ€ΠΊΠΈ Π±ΠΈΡ‚ΠΎΠ² этого значСния Π² Π²ΠΈΠ΄Π΅ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹ ΠΈΠ½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° (long):

union {

 long intValue_;

 char* pointerValue_;

};


pointerValue_ = somePointer;

long int gotcha = intValue_;

Π—Π΄Π΅ΡΡŒ Π΅ΡΡ‚ΡŒ Π΄Π²Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹.

β€’ Π”Π°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ слишком ΠΌΠ½ΠΎΠ³ΠΎΠ³ΠΎ. Он полагаСтся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ sizeof(long) ΠΈ sizeof(char*) Ρ€Π°Π²Π½Ρ‹ ΠΈ Ρ‡Ρ‚ΠΎ ΠΈΡ… Π±ΠΈΡ‚ΠΎΠ²Ρ‹Π΅ прСдставлСния ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹. Π­Ρ‚ΠΈ утвСрТдСния справСдливы Π½Π΅ для всСх Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 91).

β€’ ΠžΠ½ скрываСт своС ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ°ΠΊ ΠΎΡ‚ Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠ°, Ρ‚Π°ΠΊ ΠΈ ΠΎΡ‚ компилятора. Π˜Π³Ρ€Ρ‹ с объСдинСниями Π·Π°Ρ‚Ρ€ΡƒΠ΄Π½ΡΡŽΡ‚ для компилятора поиск ошибок, связанных с Ρ‚ΠΈΠΏΠ°ΠΌΠΈ, Π° для Ρ‡Π΅Π»ΠΎΠ²Π΅ΠΊΠ° β€” выявлСниС логичСских ошибок.

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

Если Π΄Π²Π΅ POD-структуры ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π»Π΅Π½Π°ΠΌΠΈ объСдинСния ΠΈ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с ΠΏΠΎΠ»Π΅ΠΉ ΠΎΠ΄Π½ΠΈΡ… ΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Ρ‚ΠΈΠΏΠΎΠ², ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… ΠΏΠΎΠ»Π΅ΠΉ, Π° Π·Π°Ρ‚Π΅ΠΌ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ.

Бсылки

[Alexandrescu02b] β€’ [Stroustrup00] Β§C.8.2 β€’ [Sutter04] Β§36

98. НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ нСизвСстныС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ (троСточия)

РСзюмС

НаличиС Ρ‚Ρ€ΠΎΠ΅Ρ‚ΠΎΡ‡ΠΈΠΉ Π² Π‘++ β€” опасноС наслСдиС Π‘. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ ΠΈΡ… Π² своих ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ…; ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ вмСсто этого высокоуровнСвыС конструкции ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π‘++.

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ количСством Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² достаточно ΡƒΠ΄ΠΎΠ±Π½Ρ‹, ΠΎΠ΄Π½Π°ΠΊΠΎ использованиС нСизвСстных Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π² стилС C β€” Π½Π΅ Π»ΡƒΡ‡ΡˆΠΈΠΉ способ получСния Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Π­Ρ‚ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Ρ‹Ρ… нСдостатков.

β€’ ΠΠ΅Π΄ΠΎΡΡ‚аточная Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠΎΠ². По сути, Ρ‚Ρ€ΠΎΠ΅Ρ‚ΠΎΡ‡ΠΈΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ компилятору: "Π’Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈ всС ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ. Π‘ этого ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° я всС Π±Π΅Ρ€Ρƒ Π½Π° сСбя, ΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ reinterpret_cast". (Π‘ΠΌ. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 92).

β€’ Π‘ильноС связываниС ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ согласования Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ΄Π° Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ. ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Ρ‚ΠΈΠΏΠΎΠ² языком оказываСтся ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ½Ρ‹Π΅ способы для сообщСния ΠΎ Ρ‚ΠΈΠΏΠ°Ρ… ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π’Π°ΠΊΠΈΠ΅ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, форматная строка printf) ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Ρ‹ ошибкам ΠΈ нСбСзопасны, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€Π΅Π½Ρ‹ Π½ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΌ, Π½ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ. (Π‘ΠΌ. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 99.)

β€’ ΠΠ΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Ρ‚ΠΈΠΏΠΎΠ², ΡΠ²Π»ΡΡŽΡ‰ΠΈΡ…ΡΡ классами. ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Ρ‡Π΅Π³ΠΎ Π±Ρ‹ Ρ‚ΠΎ Π½ΠΈ Π±Ρ‹Π»ΠΎ ΠΊΡ€ΠΎΠΌΠ΅ POD ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² вмСсто Ρ‚Ρ€ΠΎΠ΅Ρ‚ΠΎΡ‡ΠΈΠΉ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌΡƒ повСдСнию Π² Π‘++. К соТалСнию, Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ компиляторов Π΄Π°ΠΆΠ΅ Π½Π΅ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π°Π΅Ρ‚ ΠΎΠ± этом.

β€’ ΠΠ΅ΠΈΠ·Π²Π΅ΡΡ‚Π½ΠΎΠ΅ количСство Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π”Π°ΠΆΠ΅ Π² случаС ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ количСством Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, min) Π²Π°ΠΌ всС Ρ€Π°Π²Π½ΠΎ трСбуСтся ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ», ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ количСство ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². (Как Π½ΠΈ смСшно, Π½ΠΎ это, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π΅ свойство, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ являСтся Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΈΠΌ прСпятствиСм ΡˆΠΈΡ€ΠΎΠΊΠΎΠΌΡƒ Ρ€Π°ΡΠΏΡ€ΠΎΡΡ‚Ρ€Π°Π½Π΅Π½ΠΈΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ числом Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ².)

Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ Ρ‚Ρ€ΠΎΠ΅Ρ‚ΠΎΡ‡ΠΈΠΉ Π² сигнатурах Π²Π°ΡˆΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. Π˜Π·Π±Π΅Π³Π°ΠΉΡ‚Π΅ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ количСством Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² со своими собствСнными сигнатурами, Π΄Π°ΠΆΠ΅ Ссли это Π²ΠΏΠΎΠ»Π½Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π‘, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ sprintf. Π’Ρ‹Π·ΠΎΠ²Ρ‹ sprintf часто выглядят Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚Π½Ρ‹ΠΌΠΈ ΠΈ простыми для понимания, Ρ‡Π΅ΠΌ эквивалСнтныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ с использованиСм форматирования stringstream ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² operator<< β€” Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ Π»Π΅Π³Ρ‡Π΅ ΡΠ΅ΡΡ‚ΡŒ Π² ΠΌΠ°ΡˆΠΈΠ½Ρƒ, Π½Π΅ ΠΎΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½Π½ΡƒΡŽ рСмнями ΠΈ ΠΏΠΎΠ΄ΡƒΡˆΠΊΠΎΠΉ бСзопасности, Π΄Π° Π΅Ρ‰Π΅ ΠΈ Π±Π΅Π· Π΄Π²Π΅Ρ€Π΅Ρ†. Удобства ΠΏΡ€ΠΈ использовании Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½Π΅ стоят Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈ этом риска. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π² стилС printf ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой ΡΠ΅Ρ€ΡŒΠ΅Π·Π½ΡƒΡŽ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ бСзопасности (см. [Cowan01]), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ имССтся цСлая ΠΎΡ‚Ρ€Π°ΡΠ»ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ инструмСнтария для поиска ошибок Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ€ΠΎΠ΄Π° (см. [Tsai01]).

Π›ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ бСзопасныС Π² смыслС Ρ‚ΠΈΠΏΠΎΠ² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ количСство Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΈΠ½Ρ‹ΠΌΠΈ срСдствами. НапримСр, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° форматирования [Boost] ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ новСйшиС срСдства Π‘++ для совмСщСния бСзопасности со ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒΡŽ ΠΈ удобством.

Бсылки

[Boost] β€’ [Cowan01] β€’ [Murray93] Β§2.6 β€’ [Sutter04] Β§2-3 β€’ [Tsai01]

99. НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ нСбСзопасныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

РСзюмС

Π’Ρ‹ ΠΆΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ просрочСнныС лСкарства? И Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΈ "Π°Π½Ρ‚ΠΈΠΊΠ²Π°Ρ€Π½Ρ‹Π΅", Π½ΠΎ нСбСзопасныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ способны Π½Π°Π²Ρ€Π΅Π΄ΠΈΡ‚ΡŒ Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΡŽ Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ.

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

Π˜ΠΌΠ΅Π΅Ρ‚ΡΡ Ρ‚Ρ€ΠΈ основныС ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

β€’ Π£Π½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ Ρ‚Π°ΠΊΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΡΠ²Π»ΡΡŽΡ‚ΡΡ автоматичСскиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π²Ρ‹ΡˆΠ΅Π΄ΡˆΠΈΠ΅ ΠΈΠ· области видимости, ΠΈ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ динамичСскиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π²Ρ‹ Π²Ρ‹Π·Π²Π°Π»ΠΈ дСструктор ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Π΅Π³ΠΎ врСмя ΠΆΠΈΠ·Π½ΠΈ истСкло, ΠΈ Π»ΡŽΠ±Ρ‹Π΅ дСйствия с Π½ΠΈΠΌ нСбСзопасны ΠΈ приводят ΠΊ нСпрСдсказуСмым послСдствиям.

β€’ Π‘СмантичСски Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Π’ΠΈΠΏΠΈΡ‡Π½Ρ‹Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ "висячиС" ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ p послС выполнСния delete p;) ΠΈ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, vector<T>::iterator i послС вставки Π² Π½Π°Ρ‡Π°Π»ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ обращаСтся ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€). Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ висячиС ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ ΠΈ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹, ΠΈ послСдниС часто нСпосрСдствСнно содСрТат ΠΏΠ΅Ρ€Π²Ρ‹Π΅. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ нСбСзопасно ΠΈ нСпрСдсказуСмо Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ с Ρ‚Π°ΠΊΠΈΠΌΠΈ указатСлями ΠΈ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Π°ΠΌΠΈ, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ присваивания Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠ³ΠΎ значСния Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, p = new Object; ΠΈΠ»ΠΈ i = v.begin();).

β€’ ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±Ρ‹Π»ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ. ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, "ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅" ΠΏΡƒΡ‚Π΅ΠΌ прСобразования указатСля с использованиСм reinterpret_cast (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 92) ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ Π³Ρ€Π°Π½ΠΈΡ† массива.

Никогда Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈ Π΅Π³ΠΎ коррСктности. НС Ρ€Π°Π·Ρ‹ΠΌΠ΅Π½ΠΎΠ²Ρ‹Π²Π°ΠΉΡ‚Π΅ Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ. НС Π΄Π΅Π»Π°ΠΉΡ‚Π΅ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈ Ρ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ delete; освобоТдСнная ΠΏΠ°ΠΌΡΡ‚ΡŒ β€” это освобоТдСнная ΠΏΠ°ΠΌΡΡ‚ΡŒ, ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ ΠΊ Π½Π΅ΠΉ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Π½ΠΈ ΠΏΡ€ΠΈ ΠΊΠ°ΠΊΠΈΡ… условиях. НС ΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ ΠΈΠ³Ρ€Π°Ρ‚ΡŒΡΡ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΏΡƒΡ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π° дСструктора Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, obj.~T()) с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‰Π΅Π³ΠΎ new (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 55).

НС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ нСбСзопасноС наслСдство Π‘: strcpy, strncpy, sprintf ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ запись Π² Π±ΡƒΡ„Π΅Ρ€ Π±Π΅Π· ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π° Π·Π° Π΅Π³ΠΎ ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹. Ѐункция strcpy Π½Π΅ выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Π³Ρ€Π°Π½ΠΈΡ† Π±ΡƒΡ„Π΅Ρ€Π°, Π° функция [C99] strncpy выполняСт ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ, Π½ΠΎ Π½Π΅ добавляСт Π½ΡƒΠ»Π΅Π²ΠΎΠΉ символ ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π½Π° Π³Ρ€Π°Π½ΠΈΡ†Ρƒ. ОбС эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ β€” ΠΏΠΎΡ‚Π΅Π½Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ источник нСприятностСй. Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ соврСмСнныС, Π±ΠΎΠ»Π΅Π΅ бСзопасныС ΠΈ Π³ΠΈΠ±ΠΊΠΈΠ΅ структуры ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Π‘++ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 77). Они Π½Π΅ всСгда ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ бСзопасны (Π² основном это связано с вопросами эффСктивности), Π½ΠΎ сущСствСнно мСньшС ΠΏΠΎΠ΄Π²Π΅Ρ€ΠΆΠ΅Π½Ρ‹ ошибкам ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π±ΠΎΠ»Π΅Π΅ бСзопасный ΠΊΠΎΠ΄.

Бсылки

[C99] β€’ [Sutter00] Β§1 β€’ [Sutter04] Β§2-3

100. НС рассматривайтС массивы ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½ΠΎ

РСзюмС

ΠŸΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½Π°Ρ Ρ€Π°Π±ΠΎΡ‚Π° с массивами β€” большая ошибка. К соТалСнию, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ компилятор Π½ΠΈΠΊΠ°ΠΊ Π½Π° Π½Π΅Π΅ Π½Π΅ Ρ€Π΅Π°Π³ΠΈΡ€ΡƒΠ΅Ρ‚. НС ΠΏΠΎΠΏΠ°Π΄Π°ΠΉΡ‚Π΅ΡΡŒ Π² эту Π»ΠΎΠ²ΡƒΡˆΠΊΡƒ!

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ слуТат ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ для Π΄Π²ΡƒΡ… Ρ†Π΅Π»Π΅ΠΉ: Π² качСствС ΠΌΠ°Π»ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ Π² качСствС ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² для массивов (ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ массивы ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² с использованиСм Π°Ρ€ΠΈΡ„ΠΌΠ΅Ρ‚ΠΈΠΊΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ). Π’ качСствС ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈΠΌΠ΅Π΅Ρ‚ смысл Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Derived ΠΊΠ°ΠΊ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Base. Однако ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ ΠΊΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ†Π΅Π»ΠΈ, такая Π·Π°ΠΌΠ΅Π½Π° Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ массив ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Derived β€” совсСм Π½Π΅ Ρ‚ΠΎ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ массив ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Base. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сказанноС, Π·Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ ΠΌΡ‹ΡˆΡŒ, ΠΈ слон β€” ΠΎΠ±Π° ΠΌΠ»Π΅ΠΊΠΎΠΏΠΈΡ‚Π°ΡŽΡ‰ΠΈΠ΅, Π½ΠΎ это Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ»ΠΎΠ½Π½Π° ΠΈΠ· ста слонов Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎ Π΄Π»ΠΈΠ½Π΅ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅, Ρ‡Ρ‚ΠΎ ΠΈ ΠΊΠΎΠ»ΠΎΠ½Π½Π° ΠΈΠ· ста ΠΌΡ‹ΡˆΠ΅ΠΉ.