Pull to refresh

Comments 147

Непонятно в чем проблема иметь несколько ABI. Старые, новые, от сторонних компиляторов и языков программирования...

Жава уже проходила это - никому не понравилось, даже самим вендорам.

В том, что существует куча софта который уже не собирается последними компиляторами, либо существует ТОЛЬКО в бинарном виде. Этот софт (суммарно) тянет на триллионы долларов (стоимость замены). Если начнете играть с совместимостью нескольких ABI, то это все придется изобрести заново. И кто-то должен будет за эти работы заплатить. А добровольцев платить что-то не видно.

А можете перечислить сию кучу? А то аж прям интересно стало

Несколько широко известных проектов, не считая софта написанного для финансового сектора еще с начала 2000х:

  • Windows OS (~65M+ LoC)

  • Google Chrome: (~35M LoC)

  • Mozilla Firefox: (~20M LoC)

  • Adobe Photoshop: (~10M LoC)

  • Unreal Engine: (~10M LoC)

  • LLVM/Clang: (~5M LoC)

  • Blender (~4M LoC)

  • MySQL: (~2M LoC)

  • TensorFlow: (~2M LoC)

  • PostgreSQL: (~1M LoC)

    И это далеко не всё. Если предположить, что в промышленных проектах пишут в среднем 14-15 строк кода в день (это с учетом всего цикла CI/CD). То на переписывание перечисленного нужно около 38732 человеко/года. Или около $3.8 млрд с учетом накладных расходов. И то, если все это напишут с первого раза и без багов. В реальности на порядок больше. Так что гипотеза о триллионах расходов вполне оправдана.

Прикольно... Оказывается, столько софта, который не собирается последними компиляторами. Особенно порадовал закрытый софт, про который вы не знаете ничего.

Я конечно не специалист по хрому, но хром, как и brave, я прекрасно собирал в прошлом году наисвежайшей студией 22. Предполагаю, что и по остальным позициям так же. И да, последними компиляторами собирается даже древнее барахло, где ещё есть auto и register.

Так что меньше надо придумывать

Прикольно... Оказывается, столько софта, который не собирается последними компиляторами. Особенно порадовал закрытый софт, про который вы не знаете ничего.

Я конечно не специалист по хрому, но хром, как и brave, я прекрасно собирал в прошлом году наисвежайшей студией 22. Предполагаю, что и по остальным позициям так же. И да, последними компиляторами собирается даже древнее барахло, где ещё есть auto и register.

Так что меньше надо придумывать

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

Оно бы было хорошо, если бы не общие библиотеки. От просто общих до системных.

А как в отсутствии стабильного ABI делать динамически загружаемые плагины?

не использовать бинарный интерфейс?

Можно использовать и бинарный, но построенный на кроссплатформенных протоколах без завязок на ABI, например, protobuf

У меня для вас новости! Несколько ABI и так уже есть: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html

И в Windows тоже их несколько. Видели вот эти вот msvcrt2005, msvcrt2008, msvcrt2010, etc? Это ни что иное как несовместимые между собой по ABI версии стандартной библиотеки C++: https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=msvc-170

Вообще не понимаю, зачем кому-либо может понадобиться гипотетический С++ без обратной совместимости. Писать всё заново с нуля на языке идейно во многом 50-летней давности, который даже и в момент своего появления 50 лет назад был далеко не самым продвинутым... чтобы что?

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

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

Если по-честному, то C++ сам по себе - это гибрид недосмолтока 90-х с недохаскелем 2000-х, примотанный изолентой поверх Си.

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

В C++ в отличии от того же Rust есть, например, ООП с наследованием и т. п. Есть varidadic templates.

Многие решения C++ не очень элегантны (или даже очень уродливы), но он умеет буквально всё всеми способами (кроме разве что рефлексии, но и это уже добавляют) и при этом является компилируемым языком с ручным управлением памятью (что важно для задач, где требуется производительность).

Его конкуренты в основном предлагают гораздо более opionated решения типа "вы обязаны выбирать композицию вместо наследования".

Хотелось бы отметить, что слухи о влиянии ручного управления памятью на производительность сильно преувеличены. Я как раз недавно в статье приводил пример, когда в очень неудобной экпоненциально сложной задаче происходил перебор огромнейшего количества динамически создаваемых и разрушаемых списков (в несколько раз больше объёма оперативной памяти). И вот в такой задаче автоматическая сборка мусора заняла всего 50% времени выполнения. Это по сути вообще ни о чём, на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С).

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

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

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

А можно ссылку на статью? Как-то прошла мимо меня..

https://habr.com/ru/articles/859758/

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

Но мусор почему-то многие собирают руками

не понял о C++ ли вы, но я ОЧЕНЬ редко пишу free/delete.

Фактически мусор собирает компилятор благодаря raii

Далеко не всегда можно обойтись стеком.

Зачем вообще придумано размещение памяти в куче?

Любой асинхронный пул обслуживания запросов, например.

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

вектор, строка... и тд

И вот в такой задаче автоматическая сборка мусора заняла всего 50% времени выполнения. Это по сути вообще ни о чём

Наверное, я чего-то не понимаю в программировании, но когда половина времени уходит не на полезную работу, а на менеджмент памяти, то в этом нет ничего хорошего. А когда это еще и характеризуют как "по сути ни о чём", то такое ощущение, что не понимаю я вообще ничего.

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

Либо работа с большими объемами данных, где экономия 4-х байт на каждый объект приводит к снижению потребления памяти на сотни мегабайт. А с учетом того, что быстрые кэши маленькие, а загрузка в них данных из ОП медленная, то экономия на потребляемых объемах как-то сама собой трансформируется в выигрыш по скорости.

Надо ж, какой пафос! Я б ещё, может, и мог с огромным усилием поверить, что в ваших программах негде сэкономить 4 байта, кроме как на счётчике ссылок, и вот именно он разрушил бы всё оптимальное размещение в памяти. Но уж никак не в объектно-ориентированном языке C++ с повсеместными таблицами виртуальных методов, длинами векторов и прочей шнягой поддержки выполнения. С Фортраном 77 такая аргументация прошла бы, а тут вряд ли.

Наверное, я чего-то не понимаю в программировании, но когда половина времени уходит не на полезную работу, а на менеджмент памяти, то в этом нет ничего хорошего. А когда это еще и характеризуют как "по сути ни о чём", то такое ощущение, что не понимаю я вообще ничего.

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

Надо ж, какой пафос!

Вы в моих словах нашли пафос? Перечитайте, пожалуйста.

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

С чего вы взяли, что речь идет о счетчиках ссылок?

Ручное управление памятью (по крайней мере в моем мире) -- это не только ручной вызов new/delete (или malloc/calloc/free), и даже не деление на стек/хип. Это еще и использование union-ов, пулы/арены памяти и placement new. А так же агрегирование данных, когда вы объект класса A можете сделать полем класса B и память для A будет частью памяти для B (тогда как в языках с GC если у вас A -- это ссылочный тип, то частью другого ссылочного типа B вы его не сделаете).

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

Зная как вы не можете в обоснование собственных утвержений я даже и не стал заострять внимание вот на этом: "на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)". Но раз вы сами завели эту шарманку, то может поделитесь цифрами о том, насколько рукопашная реализация ООП на чистом Си выгоднее, чем поддерживаемая компилятором и рантаймом в С++?

А я разве говорил про рукопашную организацию ООП? Я имею в виду чисто процедурный стиль.

А я разве говорил про рукопашную организацию ООП?

Вы сказали вот что:

"Это по сути вообще ни о чём, на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)."

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

Я имею в виду чисто процедурный стиль.

Тогда при чем здесь ООП в C++? На C++ вы точно так же (даже надежнее и безопаснее) сможете использовать процедурный стиль, как и в Си.

Или вы в C++ видите какие-то дополнительные издержки даже на процедурный стиль в сравнении с Си?

Если в C++ писать в стиле C, то зачем тогда C++?

А если писать в стиле C++, то получается оверхед. Я не против оверхеда самого по себе, но не надо тогда говорить о великой эффективности.

Если в C++ писать в стиле C, то зачем тогда C++?

Я не говорил о том, чтобы писать на C++ в стиле Си. Читайте внимательнее, пожалуйста.

Речь шла о том, что в C++ вы запросто можете программировать в процедурном стиле, как и на Си. Только делать это будет удобнее и надежнее. За счет, например, наличия ad-hoc полиморфизма, ссылок и отсутствия неявных преобразований из void*.

Против отсутствия неявных преобразований из void* я не возражаю. Но для аргументации в пользу C++ в целом этого маловато.

А я и не аргументировал в пользу C++, я просил вас привести подтверждения того, что у C++ больше накладных расходов на поддержку ООП, чем в Си.

Вы, ожидаемо, в подтверждение собственных слов не смогли.

Я писал, что накладные расходы C++ возникают именно из-за поддержки ООП. А про поддержку ООП на Си - это ваши фантазии. Я к такому не призывал.

Я вовсе не агитирую делать подобие C++ из других языков.

Я писал, что накладные расходы C++ возникают именно из-за поддержки ООП

Уже несколько раз цитировал что именно вы написали, повторяться не буду. Просто еще раз напомню, что рассуждать о накладных расходах на что-то по сравнению с чем-то можно только в случае, если это "что-то" есть в том самом "чем-то". В Си ООП нет, поэтому оценивать накладные расходы C++ на ООП в сравнении с Си бессмысленно. Не удивительно, что фактически подтвердить свои утверждения вы не можете.

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

Именно потому, что в Си ООП нет, то накладные расходы на ООП в Си равны нулю.

Да, да, да. Поэтому когда в каком-нибудь Си-шном проекте, типа OpenSSL, потребуются аналоги виртуальных функций, которые колхозятся на структурах с указателями на функции, то это все абсолютно бесплатно. Ага.

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

Ну расскажите, пожалуйста, какие накладные расходы на ООП есть, например, у std::vector, у которого нет виртуальных методов, но есть инкапсуляция.

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

Повторю вопрос специально для вас: "какие накладные расходы на ООП есть, например, у std::vector, у которого нет виртуальных методов, но есть инкапсуляция".

Я, вроде, вам ответил. Это и есть в данном случае накладные расходы на ООП в части инкапсуляции.

Что именно в ответе Вам непонятно?

Инкапсулировали массив в std::vector – получайте неэффективный доступ по двум индексам.

Что именно в ответе Вам непонятно?

Если честно, то глубина вашей глупости.

mdspan по верх вектора религия не позволяет использовать?

Был вопрос про сам вектор.

Так-то и mdspan не нужен, достаточно выковырять из вектора массив и обойтись умножением. Только это не ответ на заданный вопрос.

Был вопрос про сам вектор.

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

Если уж вы заговорили про массив на базе вектора векторов, то вот вам примитивная реализация элементарного примера на чистом Си, без ООП и инкапсуляции:

https://godbolt.org/z/KrY3P7neK

А вот реализация этого же примера на C++ с классами и переопределением оператора квадратных скобочек:

https://godbolt.org/z/xGdfMGz8o

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

И если уж вам так припекают накладные расходы на std::vector, то попробуйте изобразить его аналог на чистом Си на простых структурах и свободных функциях. А потом с помощью этой реализации сделайте нужную вам двумерную матрицу на базе вектора векторов. И расскажите читателям этого флейма куда же денется регулярная структура в памяти и все прочее. Ведь ни ООП, ни инкапсуляции в вашей реализации не будет, а результат окажется таким же.

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

Кстати, по поводу сайта с говнокодом GitHub. Я предлагаю вам в гуглевском запросе самостоятельно заменить C++ на Fortran и убедиться, что те же самые индусы и студенты на Фортране пишут вполне эффективный код для матричных операций. И даже на ЛИСПЕ, вообще не предназначеном для таких вещей - тоже. Напрашивается одно из объяснений этого феномена, на выбор:

  1. В языке C++ используется заведомо неэффективная методология кодирования в виде применения принципов ООП к чему попало.

  2. Язык C++ сам по себе притягивает говнокодеров.

  3. Это заговор ненавистников C++, а пример нерепрезентативен (хотя его придумал мой оппонент для демонстрации преимуществ C++).

    Предлагаю вам выбрать объяснение на свой вкус или придумать своё. Я лично склоняюсь к первому.

Вы как-то извращённо рассуждаете.

Помилуйте, я вообще не рассуждаю, а всего лишь:

  • призываю вас подкреплять свои высказывания хоть какими-либо подтверждениями;

  • указываю на явные проблемы в ваших "утверждениях".

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

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

Некто @vadimr чуть выше:

Например, вектор векторов не образует в памяти регулярную структуру, такую как массив массивов

Вы настолько глупы, чтобы врать когда все ходы записаны?

PS. Если вы не поняли, а есть ощущение, что не поняли от слова совсем, то под утверждениями подразумевались в первую очередь вещи, вроде: "на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)"

А причём тут вектор векторов? Вектор векторов - совершено корректная конструкция ООП, а её внутреннее устройство мы не имеем права учитывать согласно воспетому вами принципу инкапсуляции. Или у вас тут инкапсуляция, а тут рыбу заворачиваем?

Если вы не поняли, а есть ощущение, что не поняли от слова совсем, то под утверждениями подразумевались в первую очередь вещи, вроде: "на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)"

Именно так. На Си никто ж не будет реализовывать ООП без очень веских причин.

А причём тут вектор векторов?

ХЗ, это вы приплели сюда этот пример, у себя и спрашивайте.

Вектор векторов - совершено корректная конструкция ООП

К ООП это вообще не имеет отношения.

а её внутреннее устройство мы не имеем права учитывать согласно воспетому вами принципу инкапсуляции

Инкапсуляция -- это про то, что доступ к данным объекта имеют только методы объекта. А не про то, что инкапсуляция напрочь скрывает принципы реализации.

Динамический вектор остается динамическим вектором. Хэш-таблица -- хэш-таблицей, сбалансированное двоичное дерево -- сбалансированным двоичным деревом. Их свойства останутся при них вне зависимости о того, базе ООП реализуются эти понятия или на базе старого доброго структурного программирования.

На Си никто ж не будет реализовывать ООП без очень веских причин.

Для альтернативно одаренных повторю еще раз: вы сказали о неких накладных расходах в C++. Сказанное не мешало бы подтвердить хоть какими-то количественными показателями.

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

Инкапсуляция -- это про то, что доступ к данным объекта имеют только методы объекта. А не про то, что инкапсуляция напрочь скрывает принципы реализации.

Ну уж нет. Инкапсуляция – это принцип изоляции контрактных обязательств объекта от его реализации. А то, о чём вы пишете – это сокрытие, конкретный механизм реализации инкапсуляции в языке программирования, причём необязательный. В Смоллтоке, например, вообще нет сокрытия, а это язык, из которого пошла инкапсуляция.

У Вас в голове вообще большая путаница между принципами программирования и их реализацией в C++.

Инкапсуляция – это принцип изоляции контрактных обязательств объекта от его реализации.

Во-первых, посмотрите определение инкапсуляции хотя бы в Wikipedia, самый первый абзац. Про изоляцию контракта от реализации -- это вам в модульное программирование и абстрактные типы данных.

Во-вторых, мы говорим про C++, в котором у инкапсуляции есть вполне конкретное воплощение.

В-третьих, я вас еще раз призываю завязывать с бла-бла-бла и сконцентрироваться (если сможете) на предоставлении хоть каких-либо объективных подтверждений своим высказанным выше утверждениям.

Ну или продолжайте зарабатывать себе репутацию балабола. Видимо вам это зачем-то нужно.

Я предлагаю к википедии не аппелировать, её пишут умственно неразвитые индусы. Почитайте какую-нибудь научную статью, например.

Если вы говорите про воплощение инкапсуляции в C++, то так и пишите, а не про инкапсуляцию вообще. Но тогда непонятно, чем инкапсуляция в вашем понимании отличается от агрегирования и сокрытия данных.

Объективных же подтверждений я, в отличие от вас, привёл уже очень много.

Объективных же подтверждений я, в отличие от вас, привёл уже очень много.

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

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

А я вам приводил примеры реальной практики программирования.

От вас были только общие слова и ссылки на репозитории со студенческим гонокодом.

Вы, кстати, сами читали статью, на которую ссылки дали? В частности раздел про инкапсуляцию, в которой копипаста из описания понятия "модуля" из модульного программирования.

Ну так модуль и является в числе прочего механизмом реализации инкапсуляции.

В C++ на классы свалили всю работу по реализации принципов ООП, но это совсем не обязательное решение.

Разве в питоне или джаве нельзя сделать агрегированный тип?

А вы понимаете разницу между ссылочными типами (reference types) и типами-значениями (value types) в языках с GC?

Если у вас в Java тип A -- это reference type, т.е.:

public class A {...}

то когда вы делаете член типа A в классе B (который так же reference type):

public class B {
  private A a;
  ...
}

то в B у вас хранится только ссылка на экземпляр A. И вы не можете повлиять на накладные расходы, связанные с хранением самого A и представлением ссылки на A внутри B.

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

А где у вас хранится в памяти тело агрегированного объекта относительно тела агрегирующего - это просто деталь реализации. В C++ всё равно так и так любой объект должен иметь возможность представляться ссылкой, так что сложно представить, как это различие можно практически эксплуатировать без ub. Сэкономить один указатель?

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

Правда? А если смогу?

А где у вас хранится в памяти тело агрегированного объекта относительно тела агрегирующего - это просто деталь реализации.

Ну да, ну да. Абсолютно несущественная, особенно если брать в расчет cache locality.

В C++ всё равно так и так любой объект должен иметь возможность представляться ссылкой, так что сложно представить, как это различие можно практически эксплуатировать без ub.

Простите не распарсил.

А можно встречный вопрос: вы вообще на C++ программировали?

Ну да, ну да. Абсолютно несущественная, особенно если брать в расчет cache locality.

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

А можно встречный вопрос: вы вообще на C++ программировали?

Нет, что вы, так рассуждаю. Но ваша правда в том, что погружаться в это тянет редко.

Простите не распарсил.

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

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

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

Если не нужны, то я могу разнести A и B. Или могу переместить A внутри B.

Нет, что вы, так рассуждаю.

Оно и заметно.

Даже если предположить

Может хватит ваших предположений? Давайте с фактами, а то у вас с этим как-то туго пока. Слов много, фактов нет.

что ниоткуда само по себе не следует

Еще как следует, когда у нас один объект внутри другого, а не два в разных местах.

то никто не мешает компилятору разместить в памяти вынесенный агрегированный объект сразу до или после агрегирующего

Можно ли увидеть примеры сего чуда? Это во-первых.
Во-вторых, вот у вас будет нечто вида:

class B {
  private C c = new C();
  private D d = new D();
  private A a = new A();
  ...
}

Где конструкторы C и D генерят тучу собственных мелких (или не очень) объектов. Как компилятор поймет, что рядом с B нужно размещать именно A?

Разница будет в один указатель.

Разница в один указатель -- это в два раза больше, чем те четыре, которые я привел в качестве примера.

Может хватит ваших предположений? Давайте с фактами

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

Прекрасно, начиналось все с

на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)

а закончилось общими фразами

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

Да вы просто мастер аргументировать вами же высказанные утверждения.

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

Только вот тормозят C++ программы несколько не так, чем программы на Ruby, например.

Вы удивительный человек, который находит альтернативный смысл в самых очевидных утверждениях. Действительно, мою фразу

на реализацию ООП в C++ уходит гораздо больше оверхеда (по сравнению с С)

теоретически можно понять так, что мы будем на Си реализовывать ООП тоже. Но я этого, конечно, не имел в виду. А имел в виду, что, программируя на С++, мы будем вынуждены, в отличие от Си, использовать реализацию ООП, так как на ООП построены библиотеки С++ и практика программирования на С++.

Но я этого, конечно, не имел в виду.

Вот и приходится выяснять что же вы имели в виду.

Теперь же, когда выяснили, вы приведете какие-то цифры, подтверждающие ваше утверждение? Или после общих слов о том, что все тормозят одинаково в процентном отношении относительно всего остального (или что вы там имели в виду) никаких количественных оценок уже не предполагается?

А имел в виду, что, программируя на С++, мы будем вынуждены, в отличие от Си, использовать реализацию ООП, так как на ООП построены библиотеки С++ и практика программирования на С++.

Тут бы очень хотелось выяснить кто такие "мы".

А практика программирования на C++ уже давным-давно (лет 25 минимум, а то и все 30) держится на мультипарадигменности, где ООП соседствует как с обычным процедурным подходом, так и с обобщенным программированием.

Только вот тормозят C++ программы несколько не так, чем программы на Ruby, например.

Не в секундах?

Не в секундах?

И даже не в минутах.

Что-то вы чушь какую-то пишете, если я напишу например

struct matrix 
  {
  float4 row1, row2, row3, row4;
  }

то Матрица будет размерностью 16*sizeof(float)

Это будет memory friendly и cache friendly и simd friendly в отличии от той же java это даст гигантский прирос производительности при массовой обработке

Только вот беда, в реальной прикладной программе на C++ такой структуры matrix не будет (например, потому, что массивы в С++ должны иметь константные размеры). А будет там какой-нибудь класс Matrix на базе векторов, который будет работать в 5 раз медленнее, чем питоновская библиотека numpy (которая, правда, сама написана на Си, но для Питона входит в стандартное окружение, а для C++ нет).

Можно, конечно, построить синтетический пример в вашем духе. Но в реальной массе программ на 99% всё будет не так.

Только вот беда, в реальной прикладной программе на C++

Отучаемся говорить за всех (c)

Лестная ссылка, конечно, но давайте проверим реальную практику программирования на С++:

https://github.com/usmana5809/Matrix-Operations-Cpp

Тут просто всегда матрицы 10x10.

https://github.com/akalicki/matrix

Тут так:

void Matrix::allocSpace() 
{ 
  p = new double*[rows_]; 
  for (int i = 0; i < rows_; ++i)
  { 
    p[i] = new double[cols_]; 
  } 
}

Где тут локальность в памяти?

https://gist.github.com/vnkdj5/5a33e530facb17f2dcf8bb88508cb4cd

Тут просто всегда матрицы 5x5.

https://github.com/bezlant/s21_matrix_cpp

Тут умный программист попался, использовал просто старый добрый одномерный массив безо всяких агрегаций:

matrix_ = new double[rows_ * cols_]();

https://github.com/Abhrankan-Chakrabarti/Interactive-Matrix-Calculator

Тут всегда 10x10.

https://github.com/omaraflak/Matrix

Тут прямо то, о чём я писал:

Matrix<T>(std::vector<std::vector<T> > const &array);

Ну и т.д.

Конечно, умный человек и кривой инструмент найдёт способ приспособить к делу удачным образом, но это ж не повод делать инструмент кривым.

Вы бы еще за демонстрациями на говнокод.ру сходили бы. Единственный из показанных вами репозиториев, который имеет хотя бы нормальное количество звезд -- 99 на данный момент -- содержит просто лабы по программированию: "A simple mathematical matrix class written in C++ to be reused for future assignments in my Computational Linear Algebra class."

Да еще и с откровенной припиской: "The code almost definitely constains significant bugs and solves numerous problems in a naive, inefficient, and incomplete manner."

Ну так язык программирования является инструментом для его фактических пользователей. Что можно поделать, если они такие вот? Я их не отбирал специально, просто загуглил.

Я не сомневаюсь, что лично Вы умный программист, хотя и со скверным характером, и напишете на C++ гораздо лучше, чем эти люди. Но толку-то с этого, если Ваша программа утонет в океане вот этого вот говнокода, который является типичной практикой современного программирования?

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

А теперь еще раз, может быть сейчас поймете: отучаемся говорить за всех.

Это не я, это google.com говорит за всех.

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

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

Если бы я хотел написать “в любой”, я и написал бы “в любой”. Если я не написал “в любой”, значит не в любой. Разве это непонятно?

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

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

Нет вы приводите в пример первые попавшиеся лабы, тогда как в мире нормально разработки используются готовые библиотеки, посмотрите реализацию у directxmath, Sony math, unreal, godot и куче других, графических или физических движков, и там везде будет примерно то что написал я, а в mkl матрици например на шаблонах будут, любой размерности.

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

Многие физические библиотеки написаны на Фортране, но это же не является достоинством Фортрана как языка программирования в общем контексте, не так ли?

Это какие физ библиотеки на Фортране написаны? Ну и да эти библиотеки на каком языке написаны (я по тебе что перечислил)? Вы по прежнему не догоняет, что плюсы позволяют писать быстрый код если это необходимо?

https://fortranwiki.org/fortran/show/Libraries

И половина, наверное, проприетарных библиотек.

Вот, посмотрите, например, квалификационные требования в Росатоме. Чем выше грейд – тем больше Фортрана.

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

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

Я писал о том, что C++ склоняет среднего программиста к написанию менее эффективного кода, чем Си.

Хотя на примеры из игродела я бы не советовал вам особенно упирать. Самая быстрая реализация 3d графики, которую я видел в своей жизни, была написана Полом Лутусом на реализованном им же диалекте языка Форт для Apple II. Она позволяла крутить в динамике 3d объекты на 8-разрядном процессоре 6502 с тактовой частотой 1 МГц и оперативной памятью 64 килобайта. Вот это я понимаю, это было удивительно. А на современные игровые движки указывать в плане эффективности просто смешно. Ну, разве что, они сделаны получше, чем написал бы то же самое средний индус.

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

То что вы привели примеры библиотек для фонтана, в с++ не используются библиотеки написанные на Фортране за очень очень редким исключением

И что из этого? В Фортране тоже не используются библиотеки, написанные на C++, за очень редким исключением.

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

Да, я подумал сразу про 3d, но это всё-таки очень частный случай.

Плохая репутация GC сложилась уже в текущее время. Утечки памяти сейчас одна из сильнейших проблем программ с GC. Что иронично :-)

А в программах с ручным управлением эти проблемы уже почти не возникают.

А не вписываются ли Rust и/или Carbon в то, что Вы сформулировали?

Rust уже получил определённое распространение, о чём говорится и в обсуждаемой статье. Но достаточно заметно отличается от C++.

Carbon ещё в процессе начальной разработки, minimum viable product версия 0.1 ожидается в 2025 году, а production ready 1.0 - в 2027. Но зато создаётся под эгидой упомянутого в обсуждаемой статье Чендлера Каррута в Google, с сохранением двусторонней совместимости с C++ (за счёт автоматической конвертации; по синтаксису, на мой взгляд, больше выглядит похожим на Rust, чем на C++). Тоже упомянут в обсуждаемой статье.

Эти языки не являются решениями, соответствующими сделанному Вами выводу?

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

Полноценной поддержки ООП в Расте, увы, нет. :-(

(про Карбон не знаю, а в Гоу кастрация под корень)

все кроме наследования, которое итак почти является анти-паттерном и во многих местах лучше использовать композицию/агрегацию.

Вполне полноценное ООП как по мне

Наследования в расте нет.

Полиморфизма полноценного нет ни в расте, ни в C++, потому что он требует динамической типизации.

ООП = struct ?

Тогда самый ООП язык – это Кобол, там инкапсуляции больше всего.

Полиморфизма полноценного нет ни в расте, ни в C++, потому что он требует динамической типизации.

Шаблоны/дженерики - статический полиморфизм. dyn trait/virtual - динамический полиморфизм. Чем это неполноценно?

Вообще ООП и его терминология пошли из Смоллтока. Что такое полиморфизм с точки зрения Смоллтока? Это такое положение дел, когда объект априорно ничего не знает о типе другого объекта, с которым он взаимодействует.

Например, условно, я определяю функцию half(x) как x/2. И при этом мне нафиг не нужно знать, в чём состоит смысл и реализация операции деления (а также двойки) и какой тип у переменной x. Потом когда-нибудь кто-то реализует, скажем, арифметику рациональных чисел со своим делением, а моя функция half всё так же будет работать с этими рациональными числами. И для этого даже перекомпиляция half будет не нужна, не говоря уж об априорном знании типа аргумента.

Вообще ООП и его терминология пошли из Смоллтока.

Конкретно в C++ ООП и его терминология пришли из Simula 67, который появился за несколько лет до начала работ над SmallTalk-ом.

Синтаксис объектно-ориентированных конструкций в С++ действительно имеет много общего с Симулой 67. Однако сам термин ООП и основные принципы ООП были придуманы Аланом Кеем при работе над Смоллтоком. Симула 67 была фактически зачислена в объектно-ориентированные языки задним числом, но никто там про тройку инкапсуляция-наследование-полиморфизм не думал.

Ну да, ну да. ООП было, а слова такого не было, ага.

То, что Алан Кей хорош в самовосхвалении не означает, что ООП -- это только то, что вышло из SmallTalk и имеет отношение к SmallTalk.

Но даже это не важно. Вы сослались на SmallTalk, но так и не объяснили почему для полиморфизма нужна динамическая типизация.

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

На практике антипаттерн наследование или нет зависит от предметной области и задачи.

C++ даёт выбор. Rust не даёт.

Rust не поддерживает ООП так, как С++. С Carbon ситуация вроде бы лучше, но у него синтаксис довольно существенно отличается от С++. Нужен такой язык, перенос на который кода с C++, в котором применяются только актуальные практики программирования, не потребует вообще никаких правок кода. То есть это должен быть не совсем новый язык, а просто более строгая версия C++, ограниченно-совместимая с просто С++. Какой-то Safe C++.

Чем cppfront не подходит? По-моему самое то для с++

Cppfront подходит, с ним можно пойти дальше, в частности изменив для него ABI. Моя идея состоит в том, что хватит бесконечно выпускать новые стандарты C++, которые делают его уже по сути другим языком, и всё больше усложняют его изучение, а вместо этого нужно перейти на приемника C++, такого как cppfront, и дальше вносить большие изменения уже в него, не таща за собой всё небезопасное наследство C++, подобно тому, как в своё время перешли с C на C++. При этом компиляторы могут поддерживать оба языка, подобно тому, как сейчас они поддерживают C и C++.

Вроде бы это язык D (dlang.org) - свободный от диалектов, гораздо более чистый и зрелый язык чем Carbon или Rust, но плохо освещенный. Хотя ему уже 25 лет.

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

СКОРОСТЬ! + полноценная поддержка ООП (а не серпом по яйцам как языках "на замену C++")

Как говорится, выбирайте одно из двух.

Если в Go и есть что-то хорошее, так это инструментарий.

Я аж кофе подавился. Нет, в Go плохой инструментарий.

будьте осторожны с кофе.

Но не забывайте аргументировать свои утверждения

Ну неплохо бы сначала увидеть аргументацию изначального утверждения.

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

К слову о Go. Если в Go и есть что-то хорошее, так это инструментарий. C++ по сравнению с ним – это натуральный мамонт. У C++ нет единой системы сборки, ничего даже близко похожего на единую систему управления пакетами, а еще его невероятно сложно разбирать и анализировать (это очень важно с точки зрения инструментария).

Не могу сказать что имелось ввиду хороший объективно (хотя все познается в сравнении), но как минимум хороший на фоне C++

В го плохо то, что это гуглёвское изделие. В любой момент его может запретить на территории РФ либо власть гугля, либо местная власть.

По этой логике у нас кроме 1С, C и C++ лучше ничего не использовать

Как вы себе представляете исполнение запрета гугла на использование го на территории РФ?

А запрет Интсаграмма как представляете?

Вы не видите разницы между сервисом и языком программирования?

я представляю, но не напишу, а то кто-то подумает что ему инструкцию подогнали...

У Go свой рантайм. Гугель туда мог напихать каких угодно закладок. А это ж гугель. Неужели он удержался?

ответ на ваш вопрос лежит прямо в https://github.com/golang/go

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

Я потратив неделю переписал небольшой проект с Си (stm32f7) на rust с их hal, если кто смотрел HAL от stm это просто ужас, hal у Rust оказался очень простым и прозрачным, да и код проекта вышел крайне лаконичным, без этого callcxpt и прочих loopback, в итоге бинарник вместо 27Кб весит 1.4Кб, вот даже в смятение, а не пора бы прекратить мучения и в больших проектах и перейти на Rust, останавливает только слабое знание так называемой "идиоматики" Rust, всё время срываюсь и вместо функционального стиля начинаешь вложенные циклы шпарить

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

Да понятно, что если мне cargo выплюнул набор инструкций их можно повторить на Си, другой вопрос какой ценой, самому лупить деструктуры, следить за памятью, замыкания, контейнеры? Тут всё инклюзив, больше думаешь над алгоритмом, а не как это всё разместить и передать... Если где-то ошибся - компилятор тебя по рукам ударит, а не выискивать потом откуда UB, откуда nullptr, почему Segmentation fault, оно же работало 5 суток подряд

По поводу HAL на C++ можно предложить достойный вариант? Мне не попадался как-то, а может и не искал, потому что и мысли не было что такое бывает, я пытался на голом STL что-то делать, он мне тупо память нафграментировал через какое-то время, не смог больше выделить кусок и я забил писать на С++ в STM

Конкретно для stm32f7 не подскажу - то, что мне встречалось в свободном доступе, поддерживало в основном более старые контроллеры. Вообще, таких библиотек много, но все они не настолько универсальны как HAL от ST в плане поддержки всго многообразия их контроллеров. Они просто очень часто выпускают новые семейства, универсальным библиотекам угнаться за этим можно только если начинать ещё до начала их массового выпуска.

Вот в этом и беда, что в С++ есть куча разных HAL, и нет ничего универсального. Взгляните для сравнения на embedded-hal для Rust. Если у меня проект на STM32, и вдруг понадобился WiFi, то я меняю 10 строчек кода, и 2 строки в системе сборки (Cargo.toml), и компилирую под ESP32. В С++ мне нужно переписать весь код работы с периферией.

Что мешало это сделать на С++ за ***цать лет? Да вроде ничего, язык позволяет.
Но этого нет, и вероятно уже не будет. Потому что поезд уже ушел...

Насколько я понимаю, желание сохранять ABI совместимость в ущерб развитию языка проистекает из практик некоторых популярных GNU/Linux дистрибутивов. Они так устроены, что там почти весь более-менее доступный пользовательский софт с открытыми исходниками собирается разработчиками системы и складывается в централизованный репозиторий. При этом для экономии места разработчики пытаются переиспользовать общие библиотеки-зависимости, чтобы несколько приложений грузили одну и ту же разделяемую библиотеку. Соответственно необходимо, чтобы ABI там совместимым был. Это касается в том числе и C++ библиотек. Но самая засада состоит в том, что в таком подходе необходима ещё и обратная совместимость компилятора, которым на пользовательской машине может собираться какой-то частный/проприетарный софт с библиотеками, которые установлены в системе (в том числе C++ библиотеками). Отсюда и требование совместимости ABI, вытекающие иногда в проблемы, что какой-нибудь std::unordered_map теперь не оптимизировать, т. к. это сломает ABI.

Решением этих пробелем мне видится изменение модели функционирования подобных дистрибутивов GNU/Linux - ближе к модели Windows, когда каждое приложение тянет с собою все зависимости и эти зависимости разработчик может собрать сам любой удобной ему версией компилятора. Стабильный ABI в таком подходе нужен только от базовых системных библиотек с голым Си интерфейсом - вроде glibc или kernel32.dll. Сборка всех зависимостей из исходников, кстати, это то, что в этой статье хвалится. Пример того, как этот подход работает, это язык Rust. Там ABI не стабилизирован и все зависимости собираются с приложением, что местами конечно не быстро, но в целом того стоит.

В расте это работает, потому что компилятор один и библиотек мало.

Собрать сложное C++ приложение с внешними зависимостями из исходников – очень нетривиальная задача, и иногда и неразрешимая. О чём, кстати, пишет автор статьи.

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

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

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

Чтобы исходники потерялись надо проявить уж очень выдающиеся навыки безответственности/халатности. Обычно исходники все под контролем git или аналогов, включая централизованный репозиторий и копию у каждого разработчика. Так что такой случай можно исключить и развивать C++ дальше, жертвуя бинарной совместимостью. К тому же, если кто-то умудрился исходники потерять, то и бинарники он тоже может с той же лёгкостью утратить.

Расхождение версий библиотек при сборке их из исходников это как раз не проблема. Можно не обновлять библиотеки, если не надо, а если они обновляются, то и при необходимости пропатчить их можно. А вот при зависимости от библиотек, установленных в систему, проблема как раз и проявляется, вроде приложение на новой ОС падает, потому, что установленная там libsomestuff.so не той версии.

Чтение данных другой программой - это сколько угодно можно, если форматы стабильны, в т. ч. бинарные. Но упомянутая в статье стабильность ABI к этому отношения не имеет.

Стабильность ABI – это в том числе и внутреннее представление объектов.

Вот именно - объектов. Вроде всяких там std::unordered_map. Но в файлы их никто не пишет, их сериализуют или в текстовом формате, или в бинарном, состоящих из простых структур. А на бинарное представление структур никто не собирается покушаться.

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

С пользовательскими структурами же другая история. Там расположение в памяти жёстко задано и если структура грамотно составлена, то ничего сломаться не может.

Но в файлы их никто не пишет, их сериализуют или в текстовом формате, или в бинарном, состоящих из простых структур.

“Может, бросить всё и уехать в Урюпинск?”

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

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

Так эти кривые программы и являются основным активом языка С++, хочется нам этого или нет.

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

Это абсолютно анти-системный подход. Если именно этот подход блокируют старые комитетчики с++ , то я за них. Потому что это приведет к еще большему раздуванию размеров приложений. А вот какой от этого выигрыш то будет? На 10% быстрее? Если нужно в каком то месте оптимизировать - так есть inline. Не надо в этом месте делать ABI call к библиотеке. Всю оптимизацию на компилятор не переложить, часть все равно должна выполнять прокладка между стулом и клавиатурой. Опять же, есть режим статической линковки - там пожалуйста, хоть какой abi делайте. Но то что является внешним api (а это то, что таковым явно объявляет та самая прокладка и то, что по факту составляет зависимость/библиотеку) должно быть и по abi стандартизировано.

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

Вброшу...
На мой взгляд, ещё одна существенная проблема С/С++ это синтаксис, преисполненный разными символами. Все эти *, &, ->, >>, ! и т.д.
Доводилось читать код человека, обожавшего перегружать операторы - ужасно.
Автор определяет два вида компаний, пишущих на с++. Интересно было бы узнать пропорцию. Моя догадка, что количество "молодых модных стартапов" сильно меньше "замшелых ретроградных контор". И, возможно, причина этого именно в нежелании условной молодёжи разбираться во всех оных закорючках. А было бы наоборот, первое лобби продавило бы новые стандарты и инструменты, несмотря на сопротивление второго.

П.С.
А вот бы сделали нативный компилятор питона.

А вот бы сделали нативный компилятор питона.

И что бы это дало?

Все эти *, &, ->, >>, ! и т.д.

Совершенно прекрасные символы. На работе в котлине мне их не хватает, поэтому пет-проекты дома у меня на плюсах.

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

По-моему, большая проблема в том, что приняты трехлетние промежутки, и вот прямо каждые три года вынь да положь основательно переделанный язык.
Зачем?!!!
Куда спешить? Все равно подавляющее большинство не успевает с новинками и ознакомиться, а из-за стремления воткнуть в язык всё, что можно, получается что-то вроде C# с его "привязанными веревочками" :) новыми возможностями...

Пора бы остановиться и осмотреться.

Sign up to leave a comment.