cplus-plus.ru logo
Мы переехали на cplus-plus.ru
Главная страница В закладкиО сайтеКарта сайта
Хостинг от uCoz
Добавить в закладки

Меню сайта

Полезные ссылки

Наша рассылка
Подписаться на рассылку
"C++ : cplus-plus.ru :
Рассылка статей C++"


Друзья сайта
alsproject.ru Выбор выходного разделительного конденсатора

Приветствую Вас, Гость · rss 26-Сен-2017, 11:42
Главная » 2011 » Январь » 24 » Объективные недостатки С++
17:16
Объективные недостатки С++

Объективные недостатки С++
Публикуется в рамках недели ненависти к С++ на хабре. Если вам все это еще не надоело, то добро пожаловать под кат.
Ранее уже были перечислены глупые причины для ненависти, поэтому я остановлюсь на реальных. Итак, за что же действительно стоит ненавидеть С++.
Причина первая, самая серьезная — грамматика. Язык С++ описывается контекстно зависимой грамматикой, следовательно алгоритм его разбора имеет высокую сложность. Все это выливается в конечном счете в долгие билды и в отсутствие нормальных инструментов для анализа кода. Написать парсер С++ задача весьма нетривиальная, написать инкрементальный парсер, по всей видимости вообще невозможно, именно поэтому, нормальные инструменты для анализа и рефакторинга С++ отсутствуют, а при малейшем изменении в файле, компилятор делает так много лишней работы. Вот простой пример красоты синтаксиса С++:

// выбор типа на этапе компиляции
template<bool Cond, typename A, typename B> struct Select;
...
Select<SomeConst > 0, SomeType, SomeOtherType>::result x;

Красиво, правда? :)

Вторая причина, тоже очень неприятная — отсутствие модулей. С++ использует заголовочные файлы, так же как и Си, добро пожаловать в шестидесятые. Каждый заголовочный файл, анализируется столько раз, сколько раз он включается директивой include(upd: это не совсем верно, в комментариях меня поправили). В сочетании с первым пунктом, это выливается в неприлично долгие билды. Конечно, прекомпиляция заголовочных файлов решает эту проблему, но лишь от части. Во первых, настроить прекомпиляцию задача не простая, во вторых, она спасает от повторной обработки стандартных заголовочных файлов. Существуют еще и Ваши заголовочные файлы, которые нельзя прекомпилировать, так как они иногда меняются.

Третья причина — шаблоны. Механизм шаблонов — основное преимущество С++. В этом языке нет кортежей, нет вариантных типов, нет лямбда выражений(точнее не было), но все это можно реализовать с помощью шаблонов, что и было сделано. Шаблоны, это полный по Тьюрингу, функциональный язык программирования, который выполняет вычисления над типами во время компиляции. Правда круто? Но есть один нюанс — компиляторы С++ — не очень хороши в выполнении сложных шаблонных мата-программ. Если нормальный код на С++ компилируется просто долго, то код на С++, использующий boost::lambda, boost::spirit или boost::mpl, компилируется целую вечность. Обычно, время компиляции напрямую зависит от количества типов, с которыми приходится работать компилятору. Когда вы пишете

 SomeType<int> x;

компилятор инстанциирует шаблон, создает новый тип. Когда вы пишете —

boost::tuple<int, long, std::string> myTuple;

— компилятор инстанциирует как минимум 4 новых типа, так как тип myTyple — это мета-программа, которая рекурсивно вычисляет тип кортежа. Сколько шаблонов инстанциируется в следующем примере, мне страшно представить:

std::for_each(v.begin(), v.end(),
(
switch_statement(
_1,
case_statement<0>(std::cout << constant("zero")),
case_statement<1>(std::cout << constant("one")),
default_statement(cout << constant("other: ") << _1)
),
cout << constant("\n")
)
);

В недалеком будущем, благодаря проекту Clang, эта проблема может потерять актуальность.

Причина четвертая — сообщения об ошибках. Если вы пишете обычный код, то все замечательно, вы будете получать понятные сообщения об ошибках. Если вы используете STL и (особенно)Boost, то сможете наблюдать сообщения об ошибках на несколько экранов. Это не фича компилятора, это фича языка, недостаток дизайна. Пример — есть несколько перегрузок одной функции, которые используют идиому SFINAE, для более точного управления перегрузкой. Скажем, мы хотели добиться того, что-бы определенная перегрузка вызывалась тогда, когда у типа параметра есть определенный typedef или еще что-нибудь в этом роде. В случае, если компилятор не найдет нужную перегрузку, мы получим сообщение о том, что такой функции вообще нет. Все из-за того, что тогда, когда происходит substitution falure(которое is not an error), компилятор выбрасывает функцию из списка перегрузок.
Эту проблему хотели решить в C++ 0x с помощью концептов, но видимо не судьба. Поэтому, компилятор С++ всегда будет сообщать о том, что тип/функция отсутствует, вместо того, что-бы сообщить о том, что параметром шаблона может быть только определенный тип.

В принципе, все эти проблемы можно так или иначе обойти, настроить прекомпиляцию, купить хорошую IDE, не использовать библиотеки интенсивно использующие метапрограммирование на основе шаблонов и не писать такой код :)
В качестве примера того, как нужно писать на С++, можно привести webkit.
Источник: http://habrahabr.ru
Категория: Новости | Просмотров: 1008 | Добавил: FazaNaka | Рейтинг: 5.0/1
Всего комментариев: 1
1  

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]