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)

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

Неплохо так. Примерно так и делаю, кстати. Хотя Haskell не знаю=)

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

Мы тут о поздних связываниях и ad-hoc полиморфизмах, если что.

Ага. Но все началось с вот этого вброса. Мне кажется что свою точку зрения я отстоял.

Не хотите ООП, давайте возьмем что-то вроде тайпклассов Haskell.

Извини, анон, но с Haskell-ем я тоже не знаком, а про тайпклассы слышу и вовсе впервые.

И еще предпочитаю не дискутировать на темы в которых я совсем некомпетентен.

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

Мне кажется что свою точку зрения я отстоял.

Тебе кажется. Ибо ты показал не позднее связывание по типу объекта, а обычный вызов функции по указателю. Твой вариант отличается от «классического» тем, что ты в объектах хранишь методы. А это, во-первых, оверхед по памяти, во-вторых ставит крест на «расширении» объекта(т.е. делает почти невозможным наследование, как классовое, так и прототипное), в третьих не компенсирует это гибкостью(которую мы наблюдаем с «тайпклассами»). И все это потому, что ты, действительно, мало знаешь.

И еще предпочитаю не дискутировать на темы в которых я совсем некомпетентен.

Но уже начал. Там вроде простой сишных код. Структурка с указателями на функции выделяется в отдельный тип. А дальше мы можем заполнять такую структурку(или даже несколько) для своего типа.

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

что ты, действительно, мало знаешь.

Да, мало. Чем дольше живу, тем больше это понимаю.

Но уже начал. Там вроде простой сишных код.

Скажу тебе честно, анон, я просто «съезжаю». Мне же нужно и в RL кодить. Отвлекает все это.

dvl36
()

А я почему-то заметил такую тенденцию - разработчики, предпочитающие современные и новомодные ЯП, слишком сильно доверяют всяким авто-функциям и называют пользователей своих программ, нищебродами, раз не могут купить себе современное производительное железо

sotlef
()

Все это пустая болтовня. Нету у вас никаких аргументов, особенно по поводу медленно. Медленно относительно чего? Давайте цифры. Пункт 5 вообще лол. Про юникод непонятный знак вопроса. И вообще все это смахивает на «С++ херня потому что в нем нету того, что есть в джаве».

SJ
()

Нифига себе затравка для троллинга - эта статья. Аж 11 страниц срача.

А по сути - поменяйте пару пунктов и замените С++ на любой другой язык - будет такая же статья.

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

Срача будет меньше, потому что другие языки никому нахрен не сдались :)

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

И вообще все это смахивает на «С++ херня потому что в нем нету того, что есть в джаве».

Язык, в котором нету ДАЖЕ ТОГО, что есть в какой-то убогой джаве - действительно херня.

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

Откровенное враньё.

боюсь, остальные пункты в твоем «опровержении» — такая же ложь

может ты-бы постеснялся откровенный быдлокод постить? Ну не знаешь ЯП — не пиши на нём. Зачем позориться? Я же не кидаю сюда например свой говнокод на C#, который тоже «не работает»? Ну не знаю я C# (и знать не желаю), это же не доказывает, что C# говно?

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

теперь, на примере видим, что const как сторож «эту переменную никак нельзя будет изменить» свою задачу не выполняет.

потому-что const это ПРИКАЗ. Он НЕ ОБСУЖДАЕТСЯ. Если написано const, компилятор строит свой код так, как если-бы эта переменная НИКОГДА НЕ ИЗМЕНИЛАСЬ.

Ну а если таки изменилась — ССЗБ. Это _твои_ проблемы, дорогой говнокодер.

И да, в сишечке никаких «сторожей» нет, и не было никогда. Учи BASIC или там питон.

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

Приведи, пожалуйста. пример, чтобы const после O3 что-то изменило по перфомансу

ты сам привёл такой пример: у тебя three КОНСТАНТНО РАВНО трём. Вот компилятор и НЕ изменяет. Согласись — не считать быстрее, чем считать.

В СА говорят: не нужно выполнять тупой приказ, нужно подождать, пока его отменят.

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

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

можно. В быдлокоде можно ВСЁ.

Наш стивчик отдал приказ «стой там, иди сюда». На его приказ положили болт. А он почему-то обиделся...

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

потому-что const это ПРИКАЗ. Он НЕ ОБСУЖДАЕТСЯ. Если написано const, компилятор строит свой код так, как если-бы эта переменная НИКОГДА НЕ ИЗМЕНИЛАСЬ.

А чего же он ее меняет тогда?

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

потому-что const это ПРИКАЗ. Он НЕ ОБСУЖДАЕТСЯ. Если написано const, компилятор строит свой код так, как если-бы эта переменная НИКОГДА НЕ ИЗМЕНИЛАСЬ.

А чего же он ее меняет тогда

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

А компилятор просто делает то, что ему сказано. Да, приказ тупой, и результат тупой. Он(результат) ещё и непредсказуемый...

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

какие оценки у тебя были по математической логике, математической/компьютерной лингвистике, построению компиляторов? «неуды»?

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

какие оценки у тебя были по математической логике, математической/компьютерной лингвистике, построению компиляторов? «неуды»?

деточка, хочешь похвастаться? Ну давай...

Кстати, какое это отношение к теме имеет, расскажешь? И вообще, чем ты на занятиях занимался?

emulek
()

Прочитал пару пунктов - дальше не стал, трололо почти на каждом пункте. Хехе

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

Воу, воу полегче

gcc выдаст ошибку т.к. нельзя ссылаться на константу обычным указателем (как минимум если бы вы немного разбирались в компиляторе, то он при компиляции создает таблицу констант, для более быстрого обращения к ним). Ты можешь осилить с++ (даже новый стандарт), если прочитаешь хотя бы Прата С. Язык программирования С++ Лекции и упражнения 2011 и Параллельное программирование на С++ в действии. Практика разработки многопоточных программ. И тогда у тебя в голове немного по яснеет.

anonymous
()

Зачем подобные «заметки» и пустопорожние выяснения? Кому какое дело, на каком языке ведется разработка того или иного проекта? Главное ЧТО именно является результатом, насколько широко используется и делает мир лучше. Пусть язык будет какой угодно и как угодно пусть называется.

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

стивчек?

Нет, не стивчек - компилятор. Ему дали приказ не менять, который не обсуждается. И компилятор, как ты сказал, должен строить код так, чтобы значение никогда не изменилось. Но чего-то в итоге он приказ нарушает.

А компилятор просто делает то, что ему сказано.

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

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

Ну так почему он меняет, если четко и однозначно сказали - «не менять»? Чего он приказы-то не выполняет?

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

А он генерирует

для уже другой переменной, а то что адрес совпал - ну так то программист захотел так

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

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

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

переменная != область памяти, компилятор не обязан генерировать код, который при каждой записи будет проверять - разрешено ли туда писать

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

переменная != область памяти, компилятор не обязан генерировать код, который при каждой записи будет проверять - разрешено ли туда писать

Конечно. Он это проверять должен при компиляции, а не в рантайме.

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

Он это проверять должен при компиляции

не всегда это тривиально или возможно:

struct S
{
    int a;
    const int b;
};

...

S s;
const int k;

*(&s.a + sizeof(int) * n) = 1;

тут может перезаписаться и s.b и k

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

не всегда это тривиально или возможно:

Всегда.

тут может перезаписаться и s.b и k

Очевидно, что если в структуре есть const поле то запись в нее по указателю запрещена. Ну, должна быть запрещена.

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

Всегда.
Очевидно, что если в структуре есть const поле то запись в нее по указателю запрещена.

struct S
{
    int a[1];
    const int b;
};
wota ★★
()
Ответ на: комментарий от anonymous

если в таблицах MMU записано что нельзя писать - будет исключение. #PF например на x86. а если не написано, то кто ж виноват альтернативно одарённым обжабаным, что они ни ухом ни рылом про то, как работает процессор.

ckotinko ☆☆☆
()
Ответ на: комментарий от wota

пишете говнокод а виноват с++. и кстати это все ++хейтеры изображают - везде говнокод в качестве примеров.

а причина одна - вы дебилы.

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

дебил - ты, я как раз показывал, что нет смысла предусматривать защиту от идиотов

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

Ну не переписать может? Ты уверен, что там действительно будет оно, учитывая выравнивание?

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

Ты уверен, что там действительно будет оно, учитывая выравнивание?

выравнивание можно явно задать

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

То есть не гарантируется, что переменная __действительно_ будет переписана, и, т.о., программист ссылается на неспецифицированное поведение. Здесь все в порядке. не надо ничего запрещать. В случае если поведение неспецифицировано - ты сам себе злой буратино. А вот когда оно специфицировано и меняет константное значение - это фейл.

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

Дело не в говнокоде, а в том, что компилтяор языка не выполняет отданные ему команды. Сказали константа - значит константа. Или тогда убирайте этот модификатор, раз компилятору на него похуй.

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

А эти прагмы, которыми ты выравнивание будешь задавать, в стандарте присутствуют?

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

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