LINUX.ORG.RU

10 причин почему программист на С++ может выбить много денег


24

10

Список в конце поста написан Лавсаном 2 года назад. (2011-03-23 19:56:00) (источник)
Надеюсь, автор не подаст жалобу в Роспатент за перепечатку :-)
Кстати, sudo cast lovesan.

Чтобы проверить актуальность вопроса, всю последнюю неделю я долго и нудно использовал этот список в дискуссиях. Чтобы разобрать отдельные пункты отдельно.

Временное резюме: С++ всё еще актуален по историческим причинам. Еще есть мобилки (sudo cast mono), гиперкластеры для шиндовс 3.11 (sudo cast vromanov) и базы данных. Т.к. он актуален, но не предназначен ни для чего (см. выводы в конце списка) новых специалистов по нему должно быть мало. Маленькая конкуренция на огромной области применения — огромное лавэ $$$. Вот это и есть истинная причина использовать кресты — возможность срубить €€€.

Честно говоря, «хитрый план» мне уже очень надоел, поэтому пора открыть карты.

Заодним, крестопоклонники смогут выйти на последний и решительный бой, т.к. сегодня пятница и вечером будет время пообщаться. Поклонникам мамкиного борща тоже наверняка есть что добавить, конструктивно и аргументированно.

Вот этот список:

  1. Вырвиглазный синтаксис и контекстно-зависимая грамматика
    • медленная компиляция
    • частые «internal error» в компиляторах
    • код плохо читается и его сложно поддерживать
    • разбор кода различными инструментами, вроде IDE, и его генерация - сильно затруднены
  2. ручное управление памятью
    • неудобства при работе с динамической памятью
    • утечки памяти
    • висячие ссылки
    • сегфолты
    • стандартные средства, как то malloc/new, работают медленно
    • фрагментация кучи
    • велосипедные аллокаторы на каждом шагу
      • которые далеко не факт что эффективнее malloc/new

    • велосипедные счетчики ссылок на каждом шагу, опять же
      • медленная работа
      • перерасход по памяти

    • отладка затруднена
    • написание GC, по факту, невозможно, отчасти из-за (5), (7) и (8)
  3. Никакого ABI
  4. Нестандартизированный и непредсказумый name mangling
  5. Дублирование функционала Си
    • сами фичи из Си никуда не деваются при этом
      • отчасти из-за того, что по функционалу превосходят аналоги из C++

    • запутывает новичков
    • malloc - new/new[], free - delete/delete[]
    • препроцессор - шаблоны
    • указатели - ссылки
      • ссылка не может быть NULL, что способствует появлению висячих ссылок и сегфолтов

    • структуры - классы
    • stdio - iostream
  6. Стандартная библиотека убога
    • Отсутствует даже такой функционал, как вменяемая работа со строками и многомерные массивы
      • Юникод?

  7. Слабая типизация
    • способствует ошибкам
    • затрудняет отладку
    • const не дает абсолютно никаких гарантий
    • при этом система типов невероятно переусложенена
      • в основном из-за пунктов (2), (5) и (9)
      • медленная компиляция
      • частые внутренние ошибки в компиляторах

  8. объектая система убога
    • практически никакой интроспекции
      • отладка затруднена
    • передача объектов по значению
      • понятие идентичности объекта теряет смысл
      • добавляет сложностей в управлении памятью
      • добавляет сложностей при отладке
      • используется часто, по причине (2)
        • перерасход по памяти
        • медленная работа

    • множественное наследование неудобно в использовании
      • проблема ромба по дефолту не разрешается никак

    • исключения в конструкторах гарантированно влекут утечку памяти
      • исключения в деструкторах тоже, и просто утечку - еще в лучшем случае
        • коды ошибок деструкторы и конструкторы возвращать не могут
          • ошибки в них не обработать никак
            • поэтому ими стараются не пользоваться
              • раздувание кода

    • деструктор можно вызывать до выхода из блока кода, или до delete
      • гарантированная утечка ресурсов/сегфлот
      • это не предотвратить никак, деструктор обязан быть public

    • одиночная диспетчеризация
      • виртуальные методы в конструкторах не работают
      • реализована убого
        • pure virtual function call
        • сложности в случае с множественным наследованием
        • деструкторы обязаны быть виртуальными
          • по дефолту - не виртуальные

        • никаких интерфейсов, только классы

    • порядок инициализации статических членов классов не определен
    • private, public и protected не дают никаких гарантий сокрытия данных
      • к инкапсуляции же не относятся совершенно никак

    • отсутствие «свойств»
      • вынуждает городить getter'ы и setter'ы
        • раздувание кода
        • размывание интерфейса класса

    • неявно генерирумые конструкторы, деструкторы и операторы присваивания
    • «friend» нарушают инкапсуляцию
  9. шаблоны
    • очень сильно замедляют компиляцию
    • раздувание кода
    • обфускация кода
    • результат раскрытия плохо предсказуем
    • сложности в отладке
      • километровые и плохо читаемые сообщения об ошибках при компиляции

    • нарушают инкапсуляцию
      • обязаны содержать реализацию в заголовочных файлах

    • позволяют генерировать некорректный код
  10. исключения
    • отсутствие finally/unwind-protect
      • заставляет городить классы ради одних деструкторов
        • раздувание кода
        • медленная компиляция
        • медленная работа

    • конфликтуют с другими возможностями языка
      • конструкторы/деструкторы
      • ручное управление памятью

    • работают медленно
    • малофункциональны (ср. CL condition system)

По причинам 3, 4, 5, 9 и 10 C++ совершенно неприменим для системного и низкоуровневого программирования. А по причинами 1, 2, 5, 6, 7, 8, и, опять же, 9 и 10 - и для прикладного.

У C++ нет области применения.

★★★★☆

Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от dvl36

Справедливости ради, стоит заметить, что это лишь одна из реализаций. Давайте возьмем один алгоритм. Вчера я просто проверил стандартные средства.

forCe
()
Ответ на: комментарий от forCe

Еще бы реализвать этот алгоритм на «правильных» языках и сравнить. Но вообще сортировка это не то, на чем надо сравнивать, т.к. получается результат очень далекий от реальных задач.

vromanov ★★★
()

Все верно в посте, неужели кому-то это ещё не очевидно? Умные люди мигрируют с Си++ на Си очень часто, обратное движение происходит только от недостатка опыта или ума.

metadeu5
()
Ответ на: комментарий от metadeu5

обратное движение происходит только от недостатка опыта или ума

Хорошая характеристика разработчиков GCC.

Begemoth ★★★★★
()
Ответ на: комментарий от anonymous

Тут в посте проскакивал блог автора ZeroMQ, Пропессор вроде как уже не на Си++ ориентируется, а на Сишечку для своего HNC. Это из последнего, что я видел в публичном.

metadeu5
()
Ответ на: комментарий от dvl36

Очень спорное утверждение. Вообще-то С быстрее, а этот случай с сортировкой, один из немногих, где C++ что-то показывает. И это решается с помощью

Вообще-то примерно поровну.

anonymous
()
Ответ на: комментарий от Begemoth

C++ вообще выглядит как хорошая идея поначалу, т.к. кажется, что «это же тот же самый Си, только с плюшками, плюшки можно не использовать в крайнем случае!». И только спустя время вкорячив STL, Boost и обрастая шаблонами, начинаешь понимать, что это была плохая идея, очень плохая идея.

metadeu5
()
Ответ на: комментарий от anonymous

Вообще-то примерно поровну.

Да, конечно, поровну.

3 против 8, в пользу Pure C. :)

dvl36
()
Ответ на: комментарий от vromanov

Но вообще сортировка это не то, на чем надо сравнивать, т.к. получается результат очень далекий от реальных задач.

+1. Стопудово.

dvl36
()
Ответ на: комментарий от metadeu5

И только спустя время вкорячив STL, Boost и обрастая шаблонами, начинаешь понимать, что это была плохая идея, очень плохая идея.

Конечно, ведь копипаста руками или отказ от остатков статической проверки типов куда как лучше.

Begemoth ★★★★★
()
Ответ на: комментарий от ilammy

И что, много они перевели на плюсы?

В процессе, в 4.8 уже шаблоны используются.

Begemoth ★★★★★
()
Ответ на: комментарий от metadeu5

«Вроде»? В общем, конкретные примеры в студию.

anonymous
()
Ответ на: комментарий от dvl36

Так на чем ни сравнивай - С++ может быть быстрее С. Обратное неверно, поскольку в С нет средств для оптимизации, недоступных в С++.

anonymous
()
Ответ на: комментарий от metadeu5

Значит, вы не знаете С++. Или не умеете программировать.

Человек, знающий С++, не может предпочесть ему С, кроме случаяв, обусловленных независящими от этого человека обстоятельствами.

anonymous
()
Ответ на: комментарий от anonymous

поскольку в С нет средств для оптимизации, недоступных в С++.

Сходи по ссылке, приведенной аноном, в сообщении чуть выше. http://www.linux.org.ru/forum/development/9500118?cid=9518881 (комментарий)

Посмотри, там и условия теста расписаны. (Самый быстрый на С++ vs самый быстрый на C.)

dvl36
()

Почему не стоит связываться с CL:

  • Ваши программы никто не будет использовать
anonymous
()
Ответ на: комментарий от metadeu5

Предпочитали. Новые разработки идут на многих других языках.

linux не последует примеру gcc по причине религиозных убеждений создателя.

anonymous
()
Ответ на: комментарий от metadeu5

Вы имеете в виду скорее всего достаточно старые проекты. Назовите хотя бы одну объективную причину предпочесть С. Исключения и rtti отключаются.

anonymous
()
Ответ на: комментарий от dvl36

Кстати, за исключением мелких нюансов(некоторых фич С99), сишный код программ, которые быстрее плюсовых, является кодом и на С++ тоже. Так что анон, по сути, прав.

Но вообще код немного странный. Попробую разобраться, когда будет время.

anonymous
()
Ответ на: комментарий от quasimoto

Где там сведения о реализации на С++? Переписывают ли?

Почему переписывают? Уж ты-то согласен, что С++ не хуже С?

anonymous
()
Ответ на: комментарий от anonymous

Суть истории в том, что Martin Sustrik создавал ZeroMQ на (подмножестве) C++ под LGPL и трейдмарками iMatix, потом написал в своём блоге на тему «почему нужно было писать на C и под BSD-like», форкнул Crossroads I/O чтобы избавиться от трейдмарков (всё ещё C++ и LGPL), потом начал писать снова nanomsg на Си под MIT и смотреть в сторону оптимизации ядра под её нужды (при этом «nanomsg» is a trademark of 250bpm s.r.o.).

А «не хуже» — наверно просто кому-то оно «не лучше» чтобы писать какой-нибудь специфичный системный код.

З.Ы. ну, то есть, зачем nginx С++, например? Чтобы делать foo *bar = static_cast<foo*>(ngx_palloc(pool, size)); ?)

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Ответ на: комментарий от quasimoto

Не лучше он быть не может. Хотя бы время от времени он будет вам полезен.

ну, то есть, зачем nginx С++, например? Чтобы делать foo *bar = static_cast<foo*>(ngx_palloc(pool, size)); ?

Чтобы модули писать не так убого, хотя бы. В коде nginx столько копипасты, что диву даешься. В общем, чтобы иметь нормальный код. Впрочем, nginx писал админ и тут все простительно.

anonymous
()
Ответ на: комментарий от anonymous

Не лучше он быть не может.

В умелых руках — я-то согласен. Но вот если кто-то хочет (оставим в стороне обоснованность такого желания) писать на таком «C++», который ровным счётом или почти == Си, тогда чисто организационно может быть лучше писать именно на си (C99 — с фичами на тему инициализации структур и «переменных»/«гибких» массивов).

quasimoto ★★★★
()
Ответ на: комментарий от anonymous

сишный код программ, которые быстрее плюсовых, является кодом и на С++ тоже.

Конечно, можно написать на C и откомпилировать это «плюсатым» компилятором. Но ведь это все равно будет код на C. :)

Если сравнивать по-честному, необходимо использовать в «плюсатом» варианте все сладкие плюшки, которые даёт C++, а не избегать их применения.

dvl36
()
Ответ на: комментарий от dvl36

А никто и не говорит о том, чтобы избегать код в стиле С++. Вопрос же в оптимизациях. Мест, которые нужно оптимизировать в реальных программах не так много и они легко локализуются. И тут С++ позволяет использовать все средства С + свои особенности. В остальном С++ не медленнее С, а в шаблонном коде почти так же быстр, как в случае макросов С(что используется не часто). Если сравнивать с другими языками, то между С и С++ в плане производительности разницы нет.

anonymous
()
Ответ на: комментарий от quasimoto

чисто организационно

Вот с этим согласен.

anonymous
()

Нужен новый язык для замены С/С++...

Тенденции есть - D, Go, Rust. Но результат пока не очень.

anonymous
()
Ответ на: комментарий от anonymous

Если сравнивать с другими языками, то между С и С++ в плане производительности разницы нет.

В С++ есть например очень тормозное позднее связывание, поэтому часто с++ аппликухи жутко медленно стартуют.

auto12884862
()
Ответ на: комментарий от lovesan

В удалённых. Меня забанили по ойпи, а мой ответ удалили, потому что на ЛОР должно рассуждать о ЯП, ничего о них не зная. Как и о других вещах впрочем. Но правду не скроешь! Позднее связывание ЕСТЬ!

anonymous
()
Ответ на: комментарий от lovesan

Читай по ссылке. Там в конце написано. Я специально самый простой текст по этой тематике привёл. Или поисковиком найди попонятнее, мне недосуг ужо. Буду себе новый ник выдумывать.

anonymous
()
Ответ на: комментарий от lovesan

Присоединяйтесь лучше к моему стартапу

... нас не заманишь лиспом борщистым. :D

dvl36
()
Ответ на: комментарий от anonymous

Покажите на сишечке более быстрое позднее связывание.

Это какое-такое позднее связывание в сишечке? Просвети что-ли.

dvl36
()
Ответ на: комментарий от lovesan

Присоединяйтесь лучше к моему стартапу Scalable Dynamic Cloud Lisp Enterprise Application Server

Чем UCW не угодил?

Короче, C++ говно в любом случае.

Я бы всё равно не стал бы присоединяться к столь подверженному эмоциям существу, делающему столь смелые суждения в области, в которой оно не разбирается, ни в каком деле.

anonymous
()
Ответ на: комментарий от anonymous

Покажите на сишечке более быстрое позднее связывание.

Давай, я лучше покажу тебе толстотролля. Погляди в зеркало, и вот, он там!

anonymous
()
Ответ на: комментарий от quasimoto

Это типа http://fuse.sourceforge.net/doxygen/structfuse__operations.html.

Так это и не совсем сишечка как-бы.

Педивикия: http://en.wikipedia.org/wiki/Late_binding

Late binding, or dynamic binding,[1] is a computer programming mechanism in which the method being called upon an object is looked up by name at runtime.

Нет такого в сишечке. (здесь вообще о Pure C)

dvl36
()
Ответ на: комментарий от dvl36

Это сишечка. Ещё — http://lwn.net/Articles/444910. Если совсем просто, то

struct iface {
    result_t(*method)(void* ctx, ...);
    // ...
};

struct a_impl {
    // ...
    struct iface *method_table;
};

result_t a_impl_method(void* ctx, ...)
{
    struct a_impl *this = ctx;
    // ...
}

// ...

struct iface a_default_method_table = {
    .method = a_impl_method,
    // ...
};

    struct a_impl a = { ..., &a_default_method_table };
    a.method_table->method(&a, ...);

вместо

struct IFace {
    virtual Result method(...) = 0;
    // ...
};

struct AImpl : public IFace {
    // ...
    Result method(...) {
        // ...
    }
};

    AImpl a(...);
    a.method(...);

компилируются они различно, но примерно одинаково — call *%reg / call *(%reg), то есть в вызов по указателю на конкретный метод.

Нет такого в сишечке.

В примере method_table настраивается во время выполнения, так что выбор производится во время него же.

З.Ы. Более точная ссылка — http://en.wikipedia.org/wiki/Late_binding#Late_binding_in_C.2B.2B, «name» тут это адрес (изначально с символом).

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

то есть в вызов по указателю на конкретный метод.

Ну так это же издревле известный метод. И реализовать его можно по-разному.

В ручную то, на сишечке, много чего можно сделать, язык то низкоуровневый, по большому счету. Тут, вроде, речь шла о автоматическом связывании.

Ну да ладно, это лишь о терминологии.

dvl36
()
Ответ на: комментарий от dvl36

ээээ ниже вроде уже показали , но .

у каждой струкруры тэг -( ну или адресса в динамике нарезаны на регионы , главное есть способ классифицировать в рантайме по переменной её «тип»)

и всё - получаем выбор конкретного метода по типу.

именно , что позднее связывание.

qulinxao ★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.