Обновить
8K+
34

Пользователь

6,9
Рейтинг
40
Подписчики
Отправить сообщение

Это ни о чем не говорит

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

Например вот эта статистика

Большая часть из этих репозиториев неактивны и не используются в реальных задачах. Значительная часть — наработки вкатунов и студентов, которые пробуют свои силы в новом языке. И там не учитываются размеры репозиториев — большие и маленькие репозитории вносят одинаковый вклад в статистику. Я не вижу причин считать эту статистику релевантной, и я не знаю способа адекватно измерить популярность языка, кроме опросов.

тут кто-то призывает отказаться от С++

Это спорная рекомендация, которая подвергается критике (например, здесь). Она смешивает C и C++, игнорируя, что C++ за последние 30 лет сильно улучшил memory-safety по сравнению с C — STL containers, smart pointers и т. д. (а в C++26 появился ещё и hardening стандартной библиотеки, который убирает множество случаев UB из-за невалидных итераторов, выходов за границы массива, запрещённых операций над контейнерами и пр.). Есть инструменты статического анализа, которые встраиваются в IDE и CI/CD-пайплайны и которые помогают писать безопасный код и не требуют для этого сложных действий. Нет смысла оценивать безопасность C++ отдельно от этих инструментов.

Вообще, нет смысла говорить, что один язык memory-safe, а другой нет. Нужно взять конкретный инструментарий для конкретного проекта, включая весь CI/CD пайплайн, и определить его степень memory safety. И окажется, что между современным C++ и тем же C# разница не такая значительная, как все привыкли думать. Перекрывает ли эта разница те преимущества C++, которые я перечислил в статье — это дело вкуса. Лично для меня — не перекрывает даже близко.

Ваш первый комментарий был чересчур эмоциональным и игнорировал текст статьи, поэтому я не видел смысла полностью на него отвечать. Вся критика строилась на отсутствии стандартизованных инструментов и сложности подключения библиотек (это единственные конкретные недостатки, на которые вы указали), но вы эти проблемы упомянули как-то вскользь, без должного объяснения. Притом что я эти проблемы в статье описал подробно — если вкратце, там говорится, что у С++ более фрагментированная экосистема, чем у C#, но в ней есть и стандартизация ABI в рамах каждой платформы, и пакетные менеджеры, пусть и не с такими обширными репозиториями.

Что вы все как заклинание повторяете эту заезженную мысль? Каждый второй комментатор, кажется, уже написал, что их нельзя сравнивать. Ну а я вот взял и сравнил. Получается, что можно.

Мне любопытно — там есть ещё что-нибудь, что выглядит смешно? Сама постановка вопроса "что лучше - с++ или c#", которая в среде айтишников считается чуть ли не табуированной — не кажется слишком смелой? Обещание окончательно ответить на этот "вечный вопрос" не кажется гротескно самоуверенным? Большая синяя кнопка "Объективное и беспристрастное сравнение" вместо "Читать далее" не наводит на мысли? То что я весь 1-й раздел описывал боль, связанную с разработкой на плюсах, а потом вывернул это как преимущество C++, потому что "настоящие хардкорные программисты любят, когда язык их всячески сношает и заставляет преодолевать трудности" — вам не показалось, что это с самого начала задаёт весь тон статьи? Вы не увидели долю самоиронии в том, что C++-программистам меньше платят, а я подаю это как преимущество C++? А фраза "я должен быть строг, но справедлив — формально рефлексия в C++ есть, и через несколько лет, когда её доделают, она будет лучше, чем в C#" — показалась вам абсолютно серьёзной?

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

Что забавно, о чём вы говорите? У нас тут серьёзная статья.

Статистика StackOverflow для C++ показывает рост на 3% с 2023 по 2025

TIOBE Index показывает попеременно периоды уменьшения и роста, но если брать период с 2017, то метрика популярности C++ выросла на 3.5%.

На каких данных основано ваше утверждение, что "на C++ пишут всё меньше"?

Не знал. Спасибо!

И не говорите. Я даже два плюса из названия языка не стал засчитывать, а то было бы 10:1.

Вы возрождаете мою веру в людей. Поставил бы вам сердечко, если б мог.

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

Чтобы найти максимальный элемент, всё, что нужно — это либо оператор <, либо оператор >. Это логично, и это то, чего ожидает пользователь. Делать функцию max, которая требует оператор-, да ещё и explicit operator bool — это очень странный контракт, который вызовет недоумение у ревьюеров. Я даже не знаю, как прокомментировать этот код, чтобы меня не забанили. И почему в этих операторах b._value не проверяется на null?

Использование dynamic допускает любые операции без compile-time проверок. Обе реализации функции max из статьи во время компиляции выполняют проверку, что у типа есть нужный оператор. Причём этот контракт явно декларируется в объявлении функции max, и при его нарушении вы получите ошибку компиляции, которая чётко и ясно скажет вам, что здесь не так. На каком основании вы заявляете, что этот код "такой же, как и у меня"?

К чему там вообще ToString и operator+? Что вы ими хотели сказать?

И вы мне ещё объясняете, какой код "не пройдёт PR в нормальной команде". Да вы вообще имеете хоть какое-то отношение к IT?

Снова отметим пропуск неудобных вопросов:

  • К чему была аналогия с Феррари?

  • Зачем запрещать классы внутри функций?

  • Вы всерьёз собираетесь оспаривать, что возможности шаблонов на порядки шире, чем дженериков?

  • Как использовать max для типа, у которого определён только оператор <, либо не реализован интерфейс IComparisonOperators?

  • Зачем классам через интерфейсы сообщать о себе информацию, которая и так известна на этапе компиляции?

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

У меня весь первый раздел про то что C++ менее удобен в плане линковки, работы с зависимостями и в плане UB. С чем вы спорите?

То, что не понимаете как работает линковка в шарпе
и какие минусы несёт в себе cmake

Где в статье я демонстрирую непонимание, как работает линковка в шарпе, и где — непонимание, какие минусы несёт CMake? Процитируйте оба места.

про dll hell вы предпочли не заметить

У вас плохая кратковременная память. Про dll hell вы написали в другом треде, и я ответил уточняющим вопросом.

Где это всё в моем и вашем примере?

В моём примере этого нет, тем он и прекрасен. В вашем:

static void for_each_arg(Action<object> action, params object[] args) {...}

используется массив object[], а массив в C# — это объект в куче.

Если в params передаются value types, то происходит их boxing при приведении к типу object:

for_each_arg(foo, 42);

в куче создаётся object, содержащий 42. Это ещё одна аллокация памяти в дополнение к массиву args.

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

потому взял ваш стиль, у вас вся статья такая

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

И миллионы строк кода написанного на шарпе - ну это просто все ошиблись.

А где я говорю, что писать на шарпе — это ошибка? Я вообще-то сам на нём пишу.

Можно угадаю - вы не пишите в команде?

Не угадали.

А где сравнение скорости компиляции?

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

Удобства встроенной библиотеки

В 7-м разделе статьи я подробно рассказал об "удобстве" контейнеров C# в сравнении с C++ и его итераторами.

Я за вас искренне радуюсь! Вы гораздо лучше меня умеете получать удовольствие от программирования на C#.

Да, и плюс вот это:

<Project Sdk="Microsoft.NET.Sdk">
	<PropertyGroup>
	    <OutputType>Exe</OutputType>
	    <TargetFramework>net8.0</TargetFramework>
	    <ImplicitUsings>enable</ImplicitUsings>
	</PropertyGroup>
</Project>

Но сказать-то вы этим что хотели?

Решено, и? Какое утверждение из статьи ваш намёк должен опровергнуть? Процитируйте.

Вы проигнорировали примерно половину моих вопросов. Спрошу ещё раз:

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

  • зачем вы принялись рассказывать про бинарную несовместимость в C# и про непереносимость между ОС, притом что я сам рассказываю про эти проблемы буквально в том же предложении, которое вы цитируете?

Ответьте на них, пожалуйста, а то после таких возражений остаётся впечатление, что вы не читали статью, а просто скормили её LLM, и попросили написать комментарий.

абсолютно не объективно и уж тем более не беспристрастно

То есть вы на полном серьёзе обвиняете эту статью в отсутствии объективности? Чем больше я вас читаю, тем больше убеждаюсь, что разговариваю с роботом, который не видит общую картину текста и не понимает его общий настрой. Я даже не буду вас разубеждать или что-то подсказывать — просто дам совет сначала читать статью, а потом писать комментарии.

Так и основной вопрос - зачем? С учетом implicit\explicit можно возвращать bool

Если операторы сравнения для класса возвращают другой тип, конвертируемый в bool, то вы не сможете использовать его с функцией max — это просто не скомпилируется. std::convertible_to — это пример гибкости концептов. С их помощью можно задать любые требования к параметрам шаблона. Возможности шаблонов в C++ на порядки шире, чем возможности C# дженериков. Вы всерьёз собираетесь это оспаривать?

Покажите, как в C# можно использовать функцию max для типа, у которого определён только оператор <. Либо есть все 6 операторов, но не реализован интерфейс IComparisonOperators. Писать класс-обёртку, и в нём определять 6 операторов сравнения, 5 из которых вы никогда не будете использовать? Положа руку на сердце, вы считаете, что это пример хорошей архитектуры языка?

В C++ вы выражаете требования в концепте, который сам достаёт всю информацию о классах, без помощи интерфейсов. Если для класса определён оператор <, то концепт просто это видит. Зачем классам через интерфейсы сообщать о себе информацию, которая и так известна на этапе компиляции? Это просто нелогично, и это ограничивает ваши возможности.

Из всех преимуществ шаблонов, о которых я рассказал, вы выдернули один std::convertible_to<bool>, без которого операторы сравнения могут обойтись (ибо что ещё им возвращать кроме bool), и на основе этой мелкой детали сделали обобщённую оценку на весь раздел: "Вообще вся эта секция притянута за уши". Это приём из области демагогии.

Ну точно не для того примера, который вы привели.

А что меняется для этого примера? Массив params[] перестаёт выделять память в куче? Для значимых типов перестаёт использоваться boxing? Или куда-то пропадает рантайм каст к нужному типу? Я вижу, вы решили проигнорировать технические возражения, надеясь, что никто не заметит, и сосредоточиться на вкусовщине: "то есть в плюсах это выглядит красиво? Абсолютно не читаемо". Это опять демагогия. Да и что значит нечитаемо? Во-первых, вполне читаемо, во-вторых используется обычно для классов с простым и понятным назначением, вроде function или tuple, код которых никому и не надо читать. В C# для Func написано 17 реализаций с разным числом параметров, а для ValueTuple — 8 реализаций — вот это реально нечитаемо, и к тому же ограничено по числу параметров.

Опять - зачем?

А зачем запрещать? Программист сам может решить, что для его кода хорошо, а что плохо.

Плодить простыни кода?

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

У вас все плохо в общем и целом.

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

Вы на серьезных щах

Ну это перебор. Что не так с этими комментаторами?

сравниваете то, что сравнивать не нужно.

Возражение было бы релевантным, если бы я сравнивал C++ и Excel. То, что их не нужно сравнивать — это клише. У них сильно пересекаются возможности и области применения. И их регулярно сравнивают. Выйдет какая-нибудь сложная статья по плюсам, обязательно в комментариях появится какой-нибудь г-н "Я 10 лет назад перешёл с C++ на C#, и до сих пор радуюсь своему решению и охреневаю от того, как у вас всё сложно и неудобно". А я вот, представьте, охреневаю от того как в сишарп всё сложно и неудобно.

Аналогично каждый язык хорош в какой-то своей области

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

Если не можете найти тезисы в статье, то с чем вы спорите?

А в чём проблема?

#include <print>
int main(){ std::println("Hello, world!"); }

+4 строчки на CMake.

Считайте как Вам угодно, но объективный и беспристрастный анализ показывает, что C++ выигрывает со счётом 8:1.

Хорошо что не просто послали подальше :)

Но я же объясняю, в чём ошибка, просто за пределами спойлера )

в упоминаемом вами статическом анализаторе это не ошибка, а предупреждение.

Главное, что он помогает её найти.

1
23 ...

Информация

В рейтинге
1 114-й
Зарегистрирован
Активность