Перш за все, необхідно підкреслити, що оцінювати достоїнства і, особливо, недоліки C ++ необхідно в контексті тих принципів, на яких будувався мову, і вимог, які до нього спочатку висувалися.
C ++ - надзвичайно потужна мова, що містить засоби створення ефективних програм практично будь-якого призначення, від низькорівневих утиліт і драйверів до складних програмних комплексів самого різного призначення. Зокрема:
Частково недоліки C ++ успадковані від мови-предка - Сі, - і викликані спочатку заданим вимогою можливо більшої сумісності з Сі. Це такі недоліки, як:
- Синтаксис, що провокує помилки:
- Операція присвоювання позначається як =, а операція порівняння як ==. Їх легко сплутати, при цьому операція присвоювання повертає значення, тому присвоювання на місці вираження є синтаксично коректним, а в конструкціях циклу і розгалуження поява числа на місці логічного значення також допустимо, так що помилкова конструкція виявляється синтаксично правильною. Типовий приклад подібної помилки:
if (x = 0) <операторы>
Тут в умовному операторі помилково написано присвоювання замість порівняння. В результаті, замість того, щоб порівняти поточне значення x з нулем, програма присвоїть x нульове значення, а потім інтерпретує його як значення умови в операторі if. Так як нуль відповідає логічному значенню «брехня», блок операторів в умовній конструкції не виконається ніколи. Помилки такого роду важко виявляти, але в багатьох сучасних компіляторах пропонується діагностика деяких подібних конструкцій. - Операції присвоювання (=), інкрементація (++), декрементаціі (-) та інші повертають значення. У поєднанні з великою кількістю операцій це дозволяє, хоча і не зобов'язує, створювати мають важко вираження. Наявність цих операцій в Сі було викликано бажанням отримати інструмент ручної оптимізації коду, але в даний час оптимізують компілятори зазвичай генерують оптимальний код і на традиційних висловах. З іншого боку, один з основних принципів мов Сі і C ++ - дозволяти програмістові писати в будь-якому стилі, а не нав'язувати «хороший» стиль.
- Макроси (#define) є потужним, але небезпечним засобом. Вони збережені в C ++ незважаючи на те, що необхідність в них, завдяки шаблонам і вбудованим функціям, не так вже й велика. У успадкованих стандартних Сі-бібліотеках багато потенційно небезпечних макросів.
- Деякі перетворення типів неінтуітівнимі. Зокрема, операція над беззнаковим і знаковим числами видає беззнаковий результат.
- C ++ дозволяє пропускати break в гілці оператора switch з метою послідовного виконання кількох гілок. Такий же підхід прийнятий в мові Java. Є думка, що це ускладнює розуміння коду. Наприклад, в мові C # необхідно завжди писати або break, або використовувати goto case N для явної вказівки порядку виконання.
- Препроцесор, успадкований від Сі, дуже примітивний. Це призводить з одного боку до того, що з його допомогою можна (або важко) здійснювати деякі завдання метапрограмування, а з іншого, внаслідок своєї примітивності, він часто приводить до помилок і вимагає багато дій з обходу потенційних проблем. Деякі мови програмування (наприклад, Scheme і Nemerle) мають набагато більш потужні і більш безпечні системи метапрограмування (також звані макросами, але мало нагадують макроси Сі / C ++).
- Погана підтримка модульності (по суті, в класичному Сі модульність на рівні не доступне, її забезпечення перекладено на компонувальник). Підключення інтерфейсу зовнішнього модуля через препроцесорну вставку заголовки (#include) серйозно уповільнює компіляцію при підключенні великої кількості модулів (бо результуючий файл, який обробляється компілятором, виявляється дуже великий). Ця схема без змін скопійована в C ++. Для усунення цього недоліку, багато компілятори реалізують механізм прекомпіляції заголовних файлів (англ. Precompiled header).
До власних недоліків C ++ можна віднести: