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)
Ответ на: комментарий от qulinxao

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

Разве это когда-то было проблемой? Можно с десяток разных алгоритмов реализовать с подобной функциональностью.

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

Да,да, «позднее связывание». Вот только такого понятия нет в «сишной» терминологии. «Late binding» это то, что предоставляет среда рантайма. Это принято так называть. То, что это можно навелосипедить - само собой разумеется.

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

У нас приложение написано на C, C++, bash. На bash генерится куча С++, С, html, sql кода. На С написана низкоуровневая часть типа всяких очередей, статистики, работа с базами, датами. Из уровня приложения на С - DAO, модули для nginx.

На С++ написана логика приложения, парсинг пакетов. И это реально удобно.. Удобно пользоваться std::string, vector итд. Удобно, что у нас куча енумов и нет возможности присвоить неправильное значение. Да даже IDE дает подсказку, какой метод есть у класса.

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

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

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

«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.

зогбавно в русской вике статья из времён «ранних 60ых в нии мухосранска»

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

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

линковка везде одна и та же. именно она и тормозит старт

Тут вообще не про линковку разговор вели. А еще она бывает статическая.

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

и? в данный момент в разрезе ооп objC какбе культурней С++ ( при том, что С++ как кобмайн круче objC)

а упращая objС есть С+ конкретный рантайм и макрорасширитель [] - и ты ведь не утверждаеш, что в рантайме objC( который (если не обращать внимания на яблолокин) строго расширяет С ) нет позднего связывания?

т.е при наличии «библиотеки» обязательной к использованию в группе Сразработчиков вполне есть позднее(ну и что, что велосипедное и ih) связывание.

в конце концов редактор языком(стандартом или референсом каким) не определён , и чё? на этом основание только cat?

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

Где это у него проблемы со стандартом? У D есть TDPL, формальная грамматика, удобный фронтенд, которым все пользуются. Да, огромный бюракротический орган отсутствует, но D прекрасно живет и без него. Ситуация с совместимостью явно лучше чем у C++.

Компилятор стандартный старый и оттестированный. Есть новый для GCC, еще не доделан, да.

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

и ты ведь не утверждаеш, что в рантайме objC(

Не утверждаю ибо с objC не знаком.

вполне есть позднее(ну и что, что велосипедное и ih) связывание.

В таком случае можно говорить что в C есть объекты и методы, связанные списки и хеш-таблицы, строки и итераторы, etc. Навелосипедили много всякого. Глянь на glib/gObject.

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

да. в си (ибо тьюринг :) )всё есть - и даже вполне переносимо в отличии от basic peek|poke :) /

у С++ в момент своего распространения было ровно то преимущество , которое в некотором смысле повторили в Жабе:

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

но так как некоторые оптимальные компромиссы -X лет назад перестали быть оптимальными -Y лет назад то добавлялись в С++ новые компромиссы - в итоге офигеный гримуар полное знание которого гарантирует «быть милионером»

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

Которое вы реализуете. Обычно это делают через структурки с указателями на функции. Плюсовые виртуальные методы примерно так и реализованы. Как быстрее?

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

Почитайте автора ZeroMQ, хотя бы, вполне себе объективные причины.

Ссыль? Ну или сюда список причин можно...

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

У D сборщик хреновый. И тормозной. И не отключаемый по-настоящему... И вообще язык столь же сложен, как и С++. Какой-либо существенной разницы в плане продуктивности создания проектов я не заметил. Как и в объеме кода. D чуть медленнее и чуть хуже обрабатывается напильником.

В общем, польза-то от перехода какая?

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

Обычно это делают через структурки с указателями на функции.

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

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

Почему? На практике это работает иногда даже чуть медленней. Опять же по причине больших возможностей по оптимизации у компилятора. Компилятор знает о vtbl. И даже больше - он их и создает. gcc с O3 и lto, в принципе, встраивает некоторые виртуальные вызовы. И делает это гораздо лучше, чем в случае ручных указателей на функции.

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

Вы намеренно тролите, и хотите ввести в заблуждение не смотревших D.

D по ряду вопросов (списки, типизация, CTFE, контракты), по удобству рвет питон. Сравнивать его с C++ даже не смешно.

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

Сборщик давно обещают, вроде как скоро приготовят (:

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

D по ряду вопросов (списки, типизация, CTFE, контракты), по удобству рвет питон.

А вот это смешно. Может быть нужно добавить примеров?

Сравнивать его с C++ даже не смешно.

А с чем его еще сравнивать, если это тот же С++, только с боку?

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

gcc с O3 и lto, в принципе, встраивает некоторые виртуальные вызовы.

Если встроит(inline) метод, то, вызов _этого_ метода, видимо, будет быстрее. Нужно только добавить проверку того, что метод не был заменен на другой. Если не встроит, то вызов, по идее, должен получаться медленнее, из-за бОльшего количества indirection-ов. Вызовы перегруженных методов соответственно тоже не будут быстрыми.

И делает это гораздо лучше, чем в случае ручных указателей на функции.

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

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

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

Омг, аж на один indirection больше. Вы так уверены, что это окажет больший эффект, нежели необходимость каждый раз вытаскивать vtable конкретного объекта в кеш?

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

необходимость каждый раз вытаскивать vtable конкретного объекта в кеш?

Какой такой vtable?

Кто-то что-то не правильно распарсил.

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

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

За вызов по ручному или виртуальному плюсовому ничего сказать не могу. Но вызов функции по указателю очень быстро работает. У интеля все мат функции реализованы через диспетчер, который выбирает исходя из cpuid при первом вызове. Ассемблер мне таки пришлось почитать ;)

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

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

С чего вдруг? У нас есть указатель на vtbl в объекте и есть известное значение смещения. Соответственно, никакого дополнительного уровня косвенности тут нет.

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

Ну я так понял, что у тебя есть вот такая кучка функций (фактически, vtable):

struct ISomething {
    void (*foo)(void*, int);
    bool (*bar)(void*, float);
};
И ты утверждаешь, что вставить эти функции напрямую в объект:
struct A {
    struct ISomething something_methods;
    // ...
};

// ...

struct A *obj = make_A();
obj->something_methods.foo(obj, 100);
будет быстрее и шелковистее, чем сделать одну общую табличку для всех A:
struct A {
    struct ISomething* something_methods;
    // ...
};

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

У нас есть указатель на vtbl в объекте и есть известное значение смещения.

object->vtbl+offset->method()

vs

object->method()

Я, пользуясь терминами статьи на lwn.net, говорю про «Directly embedded function pointers». Под «ручными» указателями вроде бы это подразумевается в дискуссии.

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

есть вот такая кучка функций (фактически, vtable)

Не, никакой кучки. «Directly embedded function pointers». См. ответ выше.

dvl36 ★
()

Когда этот вброс тлько полявился его очень конкретно расписал под хохлому замотиватор, недавно это сделал еще udpn, а после появления этого поста на жуйке у @Chtulhu родился такой текст:

Пацаны, я тут короче сидел за монитором и попытался скомпилить какую-то шнягу из буста, не помню какую, но внезапно компилятор сказал мне «интернал еррор» много раз. И тут я вдруг задумался — какое же говно c++! <[ апплодисменты в зале ]>

Представляете, пацаны, он дает мне stdio и iostream, и я должен выбирать. А как я выберу, это же так сложно, прямо глаза разбегаются! А вдруг я использую и первое, и второе? Совсем беспредел же получится, пацаны, видите какой говно-язык? <[ зал продолжает рукоплескать ]>

А стандартная библиотека? Она же просто ужасна! Там даже строки кривые — не спрашивайте почему, я не знаю^W^W^Wэто же очевидно! И знаете, скажу вам по секрету, я открыл ее исходник... Да, исходник самой stl! Вот вы когда-то смотрели туда? Вижу по глазам, что не смотрели. А я вот посмотрел, и ничего там не понял!!! <[ Бурное проявление недовольства в зале, апплодисменты, крики «Страуструпа на мыло!» ]>

Вот смотрите сюда, пацаны. Я нашел кусок кода, в котором используются макросы с шаблонами, конструкторы бросают исключения, написана куча велосипедных аллокаторов, память течет как из ведра. Я читал его и ужасался, на каком же говно-языке все вокруг пишут! <[ Одинокий голос из зала «а может ты сам написал этот код?», раздается несколько ударов, несогласного выносят ]>

И инкапсуляция у них нарушается всегда!!! В только представьте, пацаны — они спят и видят, как бы ее нарушить! Просыпаются, и сразу же бегут ее нарушать; засыпают, мечтая о том, как пойдут нарушать ее завтра! <[ Дамы в зале утираются платочками, всхлипывая; мужчины сидят с каменными лицами, сцепив зубы ]>

И вообще, самое страшное — этот подлый язык заставляет меня думать! Думать над освобождением памяти, думать над нормальной иерархией классов, думать над всем!!! Так дальше продолжаться не может — пора закопать его! За-ко-пать!!! Такое говно не должно оскорблять своим существованием наш священный мирок! Кто со мной?!

<[ Все, сидящие в зале, вскакивают, словно распрямившаяся пружина, и выбегают в дверь следом за лидером. Кажется, старому язычку пришел пиздец. Армия скрывается в тумане, некоторое время оттуда слышатся крики «Батт-хёрт! Батт-хёрт! Батт-хёрт!», под которые марширует этот карательный отряд, потом и они затихают вдали ]>

Из потайной дверцы в опустевший зал входит Александреску, вертя в руках блокнот. «2011 год, реактивное говно-нашествие школоты номер 9681», записывает он туда; выходит из зала, запирая дверь на ключ. На крыльце его поджидает Страуструп, они заходят в соседний паб, заказывают по кружке темного пива, и с улыбкой смотрят на экран на стене.

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

«больше двадцати лет прошло, и все повторяется», — со вздохом говорит Бьёрн, потягивая пиво.

К небоскребу достраивают еще один этаж, новый подземный паркинг. Отбитые пальцы горе-разрушителей почти зажили.

«Пацаны...», — начинает свою проповедь очередной мессия.

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

object->method()

Это не то. У тебя будет каша из методов и полей в каждом объекте. Т.е. каждый объект будет содержать еще и поля с указателями на методы(не смотря на то, что они одни и те же у всех объектов одного класса).

На практике структурку с методами выделяют или совсем в отдельную сущность(которая будет передаваться в функции отдельным параметром - получаем «одноуровневый» ad-hoc полиморфизм, чем-то похожий на тайпклассы Haskell, но без контроля со стороны компилятора) или делают точно такой же указатель на vtbl/«объект-класс».

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

У тебя будет каша из методов и полей в каждом объекте.

Никакой каши.

struct object {
// Data
 data1_t data1;
 data2_t data2;
// Methods
 method1_ret_t (*function1)();
 method2_ret_t (*function2)();
};
Все коротко, ясно и понятно. Pure C way, IMO.

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

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

И работать это должно быстро. Ибо подтягивая в кеш указатель на метод, туда, за одну транзакцию, из памяти подтянутся и поля с данными, которые, вероятно, понадобятся для обработки этим самым методом.

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

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

Нет. Он должен будет содержать все.

Все коротко, ясно и понятно.

Создай 100500 объектов и получи 100500 лишних наборов дублирующих друг друга указателей.

Это может быть полезно(например, если у тебя объекты(а не классы) часто меняют свои методы на лету). Но это плохое решение в большинстве случаев.

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

Если метод общий для всех экземпляров класса, делается обычная функция, аргументом в которую указатель на структуру(объект).

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

class A
{
public:
    explicit A(int x)
        : m_x(x)
    {
    }

    int foo()
    {
        return m_x;
    }

    virtual int f()
    {
        puts("A::f");
        return m_x;
    }

    virtual int g()
    {
        puts("A::g");
        return m_x;
    }

    virtual int h()
    {
        puts("A::h");
        return m_x;
    }

private:
    int m_x;
};

class B : public A
{
public:
    B(int x, int y)
        : A(x),
          m_y(y)
    {
    }

    virtual int f()
    {
        puts("B::f");
        return A::f() + m_y;
    }

    virtual int g()
    {
        puts("B::g");
        return m_y;
    }

    virtual int h()
    {
        puts("B::h");
        return m_y;
    }

private:
    int m_y;
};

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

У питона ужасная типизация, нет Emum-ов - это две самые бесящие меня вещи в веб-деве. Контрактное программирование очень нужно в питоне, хотя-бы из-за той же идиотской типизации и еще для многих вещей. Итераторы в D функциональнее, но это уже не так принципиально. Есть нормальные интерфейсы, что замечательно, вообще ООП очень понятное и без идиотских хаков, как на питоне.

Понятно что в основном (библиотека, list comprehension, генераторы, гринлеты) емы до питона далеко, но все же.

А с чем его еще сравнивать, если это тот же С++, только с боку?

Я даже не знаю, как ответить. D предельно удобный и продуманый язык. В нем нет ни сложных стандартных хаков (как в сях) ни идиотских маразмов (как в Java), есть некоторые неприятные моменты, но ничего критичного.

Любой человек знакомый с C-подобным синтаксисом и каким-нибудь языком, через день запишет на D (даже я). Про C++ я могу лишь процитировать «Когда начал набирать популярность C++, я попытался прочитать про него книгу… До сих пор осталась вмятина на стене за пианино, куда я ее швырнул в порыве гнева!».

Простейший пример: темплейты. В D это просто функции выполняющиеся при компиляции, с немного другим синтаксисом. Все остальное идентично обычным функциям. Все.

Что такое темплейты C++?

И так во всем, абсолютно.

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

В D это просто функции выполняющиеся при компиляции, с немного другим синтаксисом. Все остальное идентично обычным функциям. Все.

У вас какой-то свой D. Шаблоны там гораздо сложнее, чем в С++.

Вообще я смотрю вам очень понравился D. И это наверно хорошо, но я такого восторга не испытываю. По факту на написание программ на D тратится столько же времени и сил, чем на написание аналогичных программ на C++. Это вам не питон.

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

Нет. Он должен будет содержать все.

Обоснуй. Зачем применять object->init(object) вместо init_object(object), если init у всех объектов одинаковый?

Но это плохое решение в большинстве случаев.

Мы здесь вроде не о простоте реализации.

И это... ОО головного мозга не всегда хорошо работает в программировании.

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

Обоснуй. Зачем применять object->init(object) вместо init_object(object), если init у всех объектов одинаковый?

ОМГ. Вы вообще понимаете, что такое позднее связывание? У вас может быть 100500 объектов с одним foo и еще 100500 с другим. При этом остальные функции, например, у них будут совпадать полностью.

Т.е.

int f(my_object_t *obj)
{
    obj->foo(obj);
    obj->bar(obj);
}

Должен работать с объектами обоих видов(«классов»)

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

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

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

Что сложного в темплейтах D?

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

Решил кстати попробовать послать патч в phobos (std в D), в течении месяца соберусь с силами, и отпишусь как оно. (Это кстати, к вопросу о Питоне.)

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

Это риторический вопрос. Я к тому, что это адская, отдельная сущность.

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

Ты запутался, как мне кажется.

Возможно, очень мало спал.

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

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

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

в D, даже в минорных релизах, ломают больше чем за всю историю С++, достаточно посмотреть на changelog текущей версии 2.063:

http://dlang.org/changelog.html

про революции в виде D1/D2/? и говорить не стоит, и пока ситуация не изменится - это будет ЯП только для фанбоев

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

И это... ОО головного мозга не всегда хорошо работает в программировании.

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

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

Делается это обычно как-то так:

/* typeclass */
typedef struct my_typeclass {
    int (*foo)(void *);
    int (*bar)(void *, int x);
} my_typeclass_t;
 
/* some function */
/* require typeclass */
int
some_fun(my_typeclass_t * instance, void * v1, void * v2)
{
    return instance->foo(v1) + instance->foo(v2);
}
 
/* some type 1 */
typedef struct my_type1 {
    int x;
} my_type1_t;
 
/* some type 2 */
typedef struct my_type2 {
    int y;
} my_type2_t;
 
/* instance of my_typeclass by type1 */
int
type1_foo(void *self)
{
    return ((my_type1_t*)self)->x;
}
 
int
type1_bar(void *self, int x)
{
    return ((my_type1_t*)self)->x + x;
}
 
static my_typeclass_t my_type1_instance_my_typeclass = {
    &type1_foo,
    &type1_bar
};
 
/* instance of my_typeclass by type2 */
int
type2_foo(void *self)
{
    return ((my_type2_t*)self)->y * 2;
}
 
int
type2_bar(void *self, int x)
{
    return ((my_type2_t*)self)->y * x;
}
 
static my_typeclass_t my_type2_instance_my_typeclass = {
    &type2_foo,
    &type2_bar
};
 
int
main()
{
    my_type1_t v1, v2;
    v1.x = 10;
    v2.x = 100;
 
    some_fun(&my_type1_instance_my_typeclass, &v1, &v2);
}

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

У вас может быть 100500 объектов с одним foo и еще 100500 с другим. При этом остальные функции, например, у них будут совпадать полностью.

Ну и? Те, которые совпадают - object_foo(obj), те которые разные obj->bar(obj). Перезагрузка: obj->bar = &other_bar_function;

Я это уже писал, или анон читает только последний пост?

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

Вот, это уже проясняет ситуацию. Хотя D1/D2 уже кончился.

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