На C++ плотно и осмысленно программирую где-то с 1992-го года (до этого был еще небольшой период времени, когда я не знал, что C и C++ -- это два разных языка). За это время довелось наслушаться столько критики C++ и рекомендаций использовать вместо C++ другие языки, что мало не кажется :) В разное время назывались разные альтернативы: Common Lisp, Ada, Modula-2, Pascal и Object Pascal, Oberon, Java, Eiffel, C#, D, OCaml, Haskell, Rust и Go. И это не считая разной скриптодинамики вроде Python-ов с Perl-ами и Ruby-ями.
Но вот настойчивые рекомендации использовать вместо C++ старый добрый C (или как годно и молодежно говорить: сишечку) -- это какое-то дурацкое веяние последний лет...
О том, что голый C для системного программирования лучше C++, говорили всегда. Не всем C++никам это нравилось, т.к. и само системное программирование сильно разное, и на C++ можно программировать очень по разному. Но тут, действительно, можно было вести предметный спор и за plain old C были и есть весьма весомые аргументы, начиная от того, что при работе поверх голого железа жирного рантайма C++ и ряда C++ных плюшек просто не будет, заканчивая наличием C-шного компилятора практически для всех платформ, чем C++ не мог похвастаться, особенно в былые годы.
Так что касательно низкоуровневого системного программирования plain old C до сих пор имеет серьезное преимущество перед C++. И лично мне бы хотелось, чтобы это преимущество только возрастало, а C++ становился бы все более и более высокоуровневым языком.
Но вот в последние лет 5 (плюс-минус год-два) доводится наблюдать картину, когда plain old C противопоставляют C++ даже в области разработки ПО промежуточного слоя и, что совсем уже маразматично, прикладного ПО. Попробую объяснить причину этого феномена исходя из своего разумения ситуации в софтостроении.
Происходит это из-за того, что мощность вычислительной техники за последние 25-30 лет выросла настолько, что софт, работающий с приемлемой для пользователя скоростью, теперь можно писать даже на тормозящей динамике вроде Python, Ruby и JavaScript. Молодежь может не помнить, но 30 лет назад C++ оказался популярнее многих безопасных языков со сборкой мусора по одной простой причине: не хватало мощности тогдашнего железа для языков вроде SmallTalk или CommonLisp. Точнее, такое железо тоже было, но доступно оно было не только лишь всем. Я, например, учился программировать сначала на БК1001 с 16Kb RAM, затем на Robotron 1715 с 64Kb RAM, затем на IBM XT 8086 с 640Kb памяти и тактовой частотой всего в несколько мегагерц. Кстати говоря, эта XT-шка оказалась первой машиной, в которой бы жесткий диск. А на 386-ю с 4Mb памяти довелось попасть в году, кажется, 1994-м.
Двадцать лет назад не то что Python и Ruby, даже Java была слишком уж тормозной и прожорливой. И только бурное развитие электроники и микропроцессоров перевело в разряд более-менее нормально работающих инструментов сначала Java, а затем и все остальное, вроде Perl-а, Python-а и Ruby.
Как бы то ни было, если изначально Python и Ruby использовались как продвинутые bat- или sh-файлы, а JavaScript применялся только для того, чтобы замораживать или размораживать пару кнопок на формочке в веб-страничке, то со временем стало возможно использовать эти языки для разработки нормальных, полноценных приложений. Ну а в местах, где скорости все-таки не хватает или же нужно получить доступ к какому-то системному API, используются расширения, написанные на C.
Отсюда и появляется когорта разработчиков, которые знают Python или JavaScript плюс немножко знают C. И, может быть, когда-то краем глаза видели C++. Или только слышали про C++ городские легенды о том, что если C и позволяет легко прострелить себе ногу, то уж в C++ в этом случае нога не просто простреливается, а отстреливается нахрен, вместе с яйцами и изрядным куском спинного мозга, а в образовавшуюся дыру вытекают остатки головного мозга. Причем априори понятно, что у человека, выбравшего C++ в качестве языка реализации в голове могут быть лишь остатки головного мозга, т.к. любому нормальному разработчику понятно, что брать C++ нельзя ни в коем случае. Если уж нужна скорость, то старая, добрая, можно сказать, ламповая сишечка и все.
Видимо, остатки моего головного мозга давным-давно вытекли в дыры после отстрела ног и прочих конечностей за более чем 20-летнюю работу с C++... Но понять, как можно выбирать plain old C для прикладной разработки вместо С++ в современных условиях не могу. Сам я в начале 90-х с чистого C ушел на C++ как только понял, насколько проще и безопаснее программировать на C++, не сильно проигрывая в скорости. И это был очень древний C++, в котором не было ни шаблонов, ни исключений, а результат new нужно было проверять на 0. С тех пор прошло более 20 (двадцати, Карл!) лет. Уже C++98 был намного лучше, чем C++ в 92-м. А про современный C++ и говорить не приходится.
И вот зная все это, и даже постарев и осознав, что в Интернетах больных на голову, но активно выражающих себя идиотов гораздо больше, чем где-либо, все равно не перестаю удивляться, как можно всерьез советовать использовать plain old С вместо С++. Еще раз: старый C вместо современного C++.
Если среди читателей есть приверженцы старой ламповой сишечки, то скажите, вы всерьез предпочитаете писать такой код:
#include <stdio.h> #include <stdlib.h> int main() { const size_t N = 102400; unsigned int * v = (unsigned int *)malloc( N * sizeof(unsigned int) ); if( !v ) abort(); for( unsigned int *p = v, *e = v + N; p != e; ++p ) *p = 1; unsigned int r = *v; for( unsigned int *p = v+1, *e = v + N; p != e; ++p ) r += *p; free(v); printf( "%u\n", r ); return 0; } |
Вместо вот такого:
#include <vector> #include <iostream> #include <numeric> int main() { using namespace std; vector< unsigned int > v( 102400, 1 ); auto r = accumulate( ++begin(v), end(v), *begin(v) ); cout << r << endl; return 0; } |
Вы это серьезно?
Если да, то попробуйте в приведенном выше примере поменять тип элемента динамического массива с unsigned int на short. Где это будет сделать проще?
И это самая тривиальная задачка. Что уже говорить про более сложные ситуации. Сколько усилий вам нужно будет приложить, чтобы реализовать в C такую вещь, как "множество чисел"? А такую, как Boost.MultiIndex?
Так что творятся в мире какие-то странные вещи, недоступные моему пониманию. Когда C используется для написания ядер ОС, драйверов, встраиваемого ПО -- тут без вопросов, у C здесь есть серьезные преимущества (хотя язык вроде Rust-а тут мог бы найти себе применение). Но вот уже на уровне чуток повыше, скажем, HTTP-сервера, СУБД, MQ и т.д., не говоря уже про прикладные приложения (особенно с продвинутым GUI) говорить о каких-то преимуществах C над C++ очень сложно. Если вообще возможно.
Комментариев нет:
Отправить комментарий