Програмування на З і С++: теорії і гіпотези

Існують два діаметрально протиставлених, але однаково поширених думки, які можна виразити як "C++ це C з класами" і "C++ і C - різні мови програмування". Загалом, не важливо, якої думки дотримуватися, але цікаве інше - у яких випадках яка з цих мов (або варіантів мови) переважно. При цьому я не хочу починати порівняння об'єктно-орієнтованого і структурного підходів до створення програмного забезпечення, тому що дуже часто в подібних дискусіях можна почути фразу вигляду недостатня об'єктно-орієнтованість мови програмування, а вона, на мій погляд, невірна: при проектуванні системи об'єктно-орієнтованість мови програмування важливої ролі не грає - об'єктно-орієнтовано програмувати можна практично на будь-якій мові програмування. Інша справа, що додаткові засоби мови, підтримуюче створення і використання об'єктів, скорочують кількість відповідних строчок коду і зменшують вірогідність помилок, але в ідеалі це не важливо.
Кардинальна різниця між C і C++ не в класах або шаблонах окремо, а в загальній ідеології: C дозволяє програмістам максимально контролювати (для мови програмування високого рівня) програму, а C++ йде по шляху ускладнення компілятора, щоб дозволити програмістові писати програму як йому буде зручно. При цьому, знову ж таки, в ідеальному випадку, компілятор мови зрозуміє бажання програміста і отриманий код буде все одно максимально ефективним (або близьким до ефективного). З одного боку, підхід C++, не може не викликати інтересу і схвалення, оскільки дає можливість створення ефективних програм не знижуючи при цьому їх читабельність або зручність нарощування. Але з іншого боку - підвищення складності компілятора зв'язане з різними труднощами, багато хто з яких до цих пір не подоланий.
Коли я тільки починав вивчати C++ (це було, напевно, років 6-7 тому), я був здивований великій кількості різко негативних думок про нього у професійних програмістів. Тоді мені це було незрозуміло, що, загалом, недивно: Бьерн Страуструп не тільки пішов по шляху ускладнення компілятора, але і по шляху ускладнення мови програмування, так що вивчення C++ це дуже довгостроковий процес і, напевно, на сьогоднішній день це найскладніша мова програмування. А оскільки протиставити що-небудь мові програмування можна тільки після того, як прийде розуміння основних ідей і більшості конструкцій мови, а так само після виконання крупних проектів на нім, то і час дитячого натхнення і радості побачивши могутнього інструменту (яким є C++) значно більше, чим у інших мов програмування.
Не дивлячись на те, що за ці 7 років C++ пройшов чималий шлях і сильно змінився, мені здається що джерело тих нарікань, які мають сенс, залишилося. Хочеться відзначити, що є велика кількість нарікань щодо безглуздих, на мій погляд, таких як вже згаданий дивний термін "Мала об'єктно-орієнтованість". Дуже часто можна почути, що C++ це не Smalltalk. Дивна думка: якщо програмістові більше подобається Smalltalk, то на нім і треба програмувати. Корінь же більшості лих, пов'язаних з C++, криється якраз в ускладненні компілятора (не дивлячись на те, що вище це ускладнення підносилося як перевага): чим складніше програма (в даному випадку, компілятор), тим більше вірогідність того, що в ній буде помилка.
Насправді, звичайно ж, якщо програма перестає працювати, то скаржитися на інструмент розробки треба в останню чергу, а спочатку слід спробувати знайти помилку в своєму початковому коді. Але чим більше стає програма, чим сильніше вона розростається, тим все більше і більше вірогідність того, що помилка в компіляторі позначиться на роботі вашої програми. Це було б ще півбіди і особливості свого компілятора програмістові слід знати, але компіляторів C++ достатньо багато і кожний з них володіє своїми власними достоїнствами і недоліками, результатом яких може стати неможливість збірки проекту під яким-небудь середовищем програмування, відмінним від первинної. Я не маю на увазі складності написання універсально переносних програм, що працюють під будь-якою операційною системою, зовсім немає.
Так як написати компілятор C простіше, ніж C++, і так як саму мову програмування C має менша кількість слизьких місць, чим C++, то два разних компілятора C (різних виробників) будуть більше схожі один на одного по поведінці, чим два компілятори C++. Окрім компілятора, велику складність при програмуванні на C++ викликає використання STL. Поза сумнівом, бібліотека шаблонів дуже зручна і корисна, але це в ідеалі. Наприклад, дуже части випадки, коли зміна що поставляється з компілятором STL на STLport, призводить до того, що програма починає працювати стабільніше. Звичайно ж, проблеми, пов'язані з помилками в компіляторах, виявляються дуже рідко. Власне тому можна вже зараз оцінити круг завдань, які краще вирішувати за допомогою C++, чим C (за наявності, звичайно ж, хороших навиків програмування в обох мовах): це практично все програми, від яких не потрібна безперервна робота 24 години в добу.
Дуже неприємно виявити, що програма, яка писалася і відладжувалася на якихось тестових прикладах, не може витримати реального навантаження і проблема криється саме в тому, що десь глибоко усередині бібліотеки, що поставляється з компілятором, не був реалізований механізм блокування доступу до ресурсу, що розділявся. Крім того, зазвичай переносні програми з одного компілятора на іншій зменшує кількість використовуваних можливостей мови програмування, тому що різні компілятори, як це ні смішно звучить, по разному відповідають стандарту. Або, точніше, не відповідають йому. А подібне обмеження на конструкції мови (одне з найобразливіших позбавлень, звичайно ж, обмеження на використання шаблонів) зводить нанівець більшість переваг С++.
У таких випадках вибір мови програмування C замість C++ вдаліший, оскільки дасть можливість спочатку зменшити кількість незрозумілих проблем, що виникають в реальній експлуатації програмного продукту. При цьому варто відзначити потенційну небезпеку C, який традиційно дозволяє програмістові робити все що завгодно, часто пропускаючи його помилки. Але ці помилки виловити іноді значно легше, ніж пояснювати різні дивності, що з'являються то тут, то там в програмах на C++. Строгіше, можна сказати, що зазвичай до програмного забезпечення, що розробляється, пред'являються якісь вимоги, пов'язані з його якістю. Ці вимоги не можуть бути настільки жорсткими, щоб зовсім виключати вірогідність наявності помилок в програмі, але чим вони сильніші, тим краще використовувати старий і перевірений в багатьох розробках C.
У решті проектів же може бути зворотна ситуація: складність розробки на C викличе збільшення термінів, пов'язане з відладкою і виявленням помилок в коді у самих програмістів. Але, повторюся, подібні помилки виявити простіше, ніж помилки в компіляторі або стандартній бібліотеці. Підводячи підсумки, хочеться сказати що останнім часом я почав відноситися з великою обережністю до використання С++ в проектах. Мені здається, що повинне пройти ще досить багато часу, щоб C++ досяг тієї стійкості і стабільності у використанні, при якій він підходитиме по своїх характеристиках для майже всіх розробок, але до цієї пори C залишається цілком гідною альтернативою йому.