Pull to refresh

Comments 79

Nullable types, вроде "int?", params[], async/await, не?

Тут по каждому пункту просто дикая дичь написана. Какой ещё ContinueWith, вы чего...

Я просто вижу, что автор вообще не понимает шарп. Ну совсем. Ни капельки. Ну не понимает и не понимает, ладно. Но статью зачем писать?

Тут по каждому пункту просто дикая дичь написана.

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

А можно всё же ваши тезисы озвучить, чтобы было понятно, что обсуждаем?

Что язык раздутый и более сложный? Или что?

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

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

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

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

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

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

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

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

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

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

Сначала сложилось впечатление, что автор стебётся. Но нет.

В C#, чтобы подключить библиотеку, вам достаточно выполнить команду 

А потом оказывается, что эта библиотека не совместима с текущим рантаймом. Удачи подключать библиотеки .net framework в .net core > 3. Примерно тоже самое касается .netcore - .net standard.

Это стирает границы между платформами и позволяет переносить компоненты приложений с одной ОС на другую

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

Но даже с учетом того ставить балл здесь за С++ - это конечно интересный вывод. Сову порвало :)

Из-за этого в C++ слишком легко допустить маленькую ошибку, которая приведёт к большим последствиям

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

Интерфейс Disposable

А еще там есть такое замечательное исключение, как HttpClient.

то в C# операторы сравнения должны возвращать именно bool и ничто иное

Очень спорно, как минимум есть implicit/explicit (или я не понял идею тут). Вообще вся эта секция немного притянута за уши, КМК. Тут как раз-таки C# намного более удобен и по синтаксису, и по ограничениям - при вызове функции сразу видно что в неё передавать и что ожидается, не нужно лезть в код или читать комментарии.

чтобы всё было чисто и аккуратно,

Долго смеялся )))) мы точно про C++ , где есть define? ))) А еще громче смеялся после

Нельзя объявлять классы внутри функций

:)

void for_each_arg(F&& f, Ts&&... xs){ (f(std::forward<Ts>(xs)), ...);}

и чем это отличается от:

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

    foreach (var arg in args) {

        action(arg);

    }

}

for_each_arg((o) => Console.WriteLine(o), 42, 3.14, "hello");

?

Формально рефлексия в C++ есть, и через несколько лет, когда её доделают, она будет лучше, чем в C#, так что это 8:0 в пользу C++

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

А потом оказывается, что эта библиотека не совместима с текущим рантаймом. Удачи подключать библиотеки .net framework в .net core > 3. Примерно тоже самое касается .netcore - .net standard.

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

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

Просто в C# проблемы бинарной совместимости возникают гораздо реже,

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

Большая часть asp.net приложений запускается либо в docker контейнерах, либо на Линукс серверах. GUI приложений на .net сейчас на порядок меньше чем серверов, но и среди них есть варианты кроссплатформы, хотя и не сказать, чтобы прям отличные. С другой стороны где есть нормальная кроссплатформа? В электроне?

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

Я не очень в курсе в каком состоянии сейчас .net инфраструктура. В прошлом были только Microsoft .NET и опенсорсный кросплатформенный mono. Последний не покрывал всей инфраструктуры .NET насколько мне известно и желающих им пользоваться в среднем было стабильно мало, не говоря уже о полной миграции. То что запускается в докере работает нынче поверх микрослоповского дотнета или это моно приложения?

. net Core - это отдельная open source версия .net, поддерживаемая Майкрософт. Появилась в 2016 году. Разработка старого .net Framework остановлена, к нему максимум патчи выходят, всё новое на .net Core. .net Core не привязан к винде, работает на линуксе, на андроиде и айфоне и в браузере через Web Assembly. .net библиотека без специфических платформенных зависимостей запускается везде. Ну и в целом очень много разработчиков пишут на Винде/маке, а потом тот же код запускается в докере на Линукс контейнерах

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

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

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

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

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

Цитата:

ABI-совместимость в C# доставляет гораздо меньше проблем — по крайней мере, для тех библиотек, которые не имеют нативных зависимостей.

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

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

Ну да, поддерживаю, к черту продавать Феррари

А это вообще о чём? Против какого положения статьи это должно послужить опровержением?

А еще там есть такое замечательное исключение, как HttpClient.

Да, есть и такое. Хотя это и не настолько важно, чтобы упоминать это в статье.

Очень спорно, как минимум есть implicit/explicit (или я не понял идею тут).

Это легко проверить: попробуйте написать код на C#, в котором используется функция max из статьи, и операторы сравнения возвращают тип, наявно конвертируемый в bool. И посмотрите, скомпилируется или нет (спойлер — нет).

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

Я привёл конкретные примеры и объяснил, чем именно в этих примерах C# неудобен. Вы считаете, что конкретно в этих примерах есть какие-то удобства, которых я не замечаю? Так расскажите о них.

А еще громче смеялся после "Нельзя объявлять классы внутри функций"

Ну приведите код, в котором внутри функции объявляется именованный класс, и который при этом компилируется.

и чем это отличается от:

Если ничем не отличается, то почему в C# сделали 17 делегатов Func вместо того чтобы использовать один, с контейнером параметров?

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

Ну и как через рефлексию достать значение приватного свойства в С++, объявленного в другой подключаемой библиотеке?

А вы опасный человек. И часто вам приходится так делать?

Насколько я знаю, в C++ это возможно с помощью std::meta::access_context::unchecked, если объявление члена доступно компилятору.

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

Проблемы всего две: абсолютно не объективно и уж тем более не беспристрастно. Вы описали кучу минусов линковки в С++, и поставили ему это в заслугу. Серьезно?

тип, наявно конвертируемый в bool

Так и основной вопрос - зачем? С учетом implicit\explicit можно возвращать bool, а операторы сделают своё дело. Вы решаете проблему, которой нет.

именно в этих примерах C# неудобен

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

внутри функции объявляется именованный класс

Опять - зачем? Плодить простыни кода? Сейчас все стремятся наоборот выносить максимум классов в отдельные файлы. Такой PR точно не пройдёт никогда.

Если ничем не отличается, то почему в C# сделали 17 делегатов Func

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

да и в коде это выглядит некрасиво

А то есть в плюсах это выглядит красиво? Абсолютно не читаемо, и если нет комментариях и описания что же она там делает - придётся смотреть код. ИМХО конечно, но мне кажется 9 из 10 PR-ов с таким кодом не пройдёт в крупном проекте.

И часто вам приходится так делать?

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

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

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

  • зачем вы принялись рассказывать про бинарную несовместимость в 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# (точнее фреймворка), а остальным параметрам он просто наголову удобнее линковки в плюсах. То, что не понимаете как работает линковка в шарпе и какие минусы несёт в себе cmake (про dll hell вы предпочли не заметить) - ну это ваши проблемы.

Для значимых типов перестаёт использоваться boxing? Или куда-то пропадает рантайм каст к нужному типу?

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

Абсолютно не читаемо". Это опять демагогия.

Угу, так и есть, потому взял ваш стиль, у вас вся статья такая - "мне так удобнее" :) И миллионы строк кода написанного на шарпе (и яве, там примерно тоже самое) - ну это просто все ошиблись. Можно угадаю - вы не пишите в команде?

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

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

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

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

  • Как использовать 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.

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

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

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

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

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

Не угадали.

Если операторы сравнения для класса возвращают другой тип, конвертируемый в bool, то вы не сможете использовать его с функцией max — это просто не скомпилируется.

А зачем он мне?

public class MyInt

{

    private int _value;

    public MyInt(int x)

    {

        _value = x;

    }

    public static MyInt operator +(MyInt a, MyInt b) => new MyInt((a?._value ?? 0) + b._value);

    

    public static MyInt operator -(MyInt a, MyInt b) => new MyInt((a?._value ?? 0) - b._value);

    public static explicit operator bool(MyInt x)

    {

        return x._value > 0;

    }

    public override string ToString()

    {

        return _value.ToString();

    }

}

public static T Max<T>(IEnumerable<T> values)

{

    using var it = values.GetEnumerator();

    if (!it.MoveNext())

        throw new ArgumentException(values);

    dynamic max = it.Current;

    while (it.MoveNext())

    {

        if ((bool)(it.Current - max))

            max = it.Current;

    }

    return (T)max;

}

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

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

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

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

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

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

Как в С++ делается следующее:

  1. Защита от подмены библиотеки?

  2. Защита от dll hell, когда у вас 5 разных версий одной и тоже библиотеки лежит в разных местах?

  3. Выбор версии библиотеки (можно использовать любую от 2.0.0.0 до 2.9.0.0, или только определенную)

  1. Можно проверить хэш-сумму библиотеки. 2+3. В Windows можно использовать LoadLibraryW (LoadLibraryExW) + GetProcAddress. Перед загрузкой библиотеки этом способом можно проверить версию библиотеки через GetFileVersionInfoSizeW + GetFileVersionInfoW + VerQueryValueW.

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

Это был не вопрос, а намек, что это всё решено в C# (ну точнее во фреймоврках) нативно

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

  1. статическая линковка, всякие ухищрения с запретом на LD_PRELOAD где-нибудь в _start секции. Ну и прочие способы защиты от TOCTOU атак.

  2. настройки линковки, конфигурация версий и путей поиска в сборочной системе

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

Как в С++ делается следующее:

  1. Защита от подмены библиотеки?

  2. Защита от dll hell, когда у вас 5 разных версий одной и тоже библиотеки лежит в разных местах?

  3. Выбор версии библиотеки (можно использовать любую от 2.0.0.0 до 2.9.0.0, или только определенную)

Эти все вопросы решены с появлением Side-by-side Assemblies и манифестов еще в Windows XP/2003

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

А потом повторите то же на C#.

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

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

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

Console.WriteLine("Hello world");

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

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

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

Сейчас уже есть file-based projects, которые состоят из одного только cs-файла без всего вот этого обвяза. Для любителей писать скрипты на C# добавили, как и возможность писать сразу код без объявления namespace, class и Main. Возможно даже кому-то это нужно (может для обучения как раз).

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

Зачем CMake? Мир намного проще устроен, все делается в одну строку:

[user@home ~]$ cat hello.cpp

extern "C" int puts(const char*); int main() { puts("hello world\n"); return 0; }

[user@home ~]$ clang++ hello.cpp && ./a.out
hello world

библиотеку, собранную MinGW, нельзя подключить к проекту на MSVC — если её интерфейс не объявлен через extern "C"

А библиотеку gcc одной версии нельзя подключить к gcc другой версии, а почему? Да потому что strtol поменялся -

undefined reference to `__isoc23_strtol' from upgrade of 3.1.3 to 3.5.4 (from vcpkg)

https://github.com/openssl/openssl/issues/29121

Скрытый текст

Сидит как-то Линус Торвальдс с утреца за компом, скукотища дикая, нумерация ядер как раз на ноль поменялась, на дворе 7.0, до номера 7.21 еще огого как долго ждать. Заняться нечем от слова совсем. И захотелось ему движухи. И взял он и прибавил __isoc23 к названию strtol, чтоб никому жизнь мёдом не казалась. А глаза у него такие добрые-добрые.

Вспоминается

 Шурик, который посыпается и орёт, увидев свои же шевелящиеся пальцы
Шурик, который посыпается и орёт, увидев свои же шевелящиеся пальцы

В чём же ошибка?

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

и кстати,

auto err = mHal.setLayerCursorPosition(mDisplay, mLayer, readSigned(), readSigned());

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

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

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

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

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

Это как сравнивать автомат (c++) с атомной бомбой (c#). Оба хороши, но только для своих задач, я так считаю

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

Я не собираюсь ничего набрасывать на вентилятор или разводить холивар, а просто хочу объективно и беспристрастно ответить

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

Свои пара центов:

Я познакомился с C# на версии 1.0, еще без дженериков. Но отметил, что пишу не менее продуктивно, за счет лучшей поддержки в Студии.

Самым большим сюрпризом оказалось - как это здорово, что не надо писать отдельно файлы .h и .сpp!

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

как это здорово, что не надо писать отдельно файлы .h и .сpp!

Странный комментарий. В современном мире уже .ixx и .сxx, в C++ уже несколько лет как завезли модули. Да и Separation of Concerns это не такая и плохая штука, отделение интерфейса от реализации. То, что в "современных" ЯП все валится в кучу - это не так уж и хорошо. Вместо того, чтоб пробежаться по заголовочному файлу - теперь нужно отдельно генерировать рядом документацию, просто чтоб пользователь библиотеки не потерялся в спецификациях и знал, что можно трогать, а что нельзя. И в IDE делать отдельные символьные browserы по иерархиям классов, т.е. .h файлы просто переехали в другое место, а суть же отделения интерфейса от реализации никуда и не делась.

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

А где сравнение скорости компиляции? Скорости разработки? Удобства встроенной библиотеки? Получите дату и время из строки на с++ .

Судью на мыло.

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

Для С-style строк даже никаких библиотек не нужно, все работает и так.


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

А так - вон в Erlang вообще изначально нет строк (некие списки символов вместо них), и ничего, отличный язык по отзывам некоторых.

Собственно почему строка, список или хештаблица должны быть частью языка, а не свободно реализуемыми и заменяемыми библиотечными функциями?

А если мне не подходит стандартная реализация строк, почему меня кто-то должен ограничивать? К примеру я пишу код для микроконтроллеров, и никакой HEAP с RAII и jemalloc мне не нужен, у меня MISRA, которая явно запрещает динамическую аллокацию памяти.

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

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

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

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

  Время компиляции в C++ действительно не радует)

Справедливости ради это только если Release/rebuild all the world делать.

А если в режиме правка-отладка, то скорость сборки и запуска даже очень больших проектов может занимать секунды. Нужно просто уметь в PCH, и разного рода модули - от .so/.dll до .ixx/.cxx, тысячи мануалов разложены в интернетах на этот счет.

Д. Лакос же уже две книжки написал про это (заново открыв для себя и мира известные еще со времен Delphi Packages, но тем не менее).

Пункт 5. Зарплата

медианная зарплата для разработчиков C++ составляет 240 000, а для C# — 250 000. Как видите, по этому показателю C++ снова оказывается впереди

Это как?

Это выгоднее работодателю, а не разработчику.

Что лучше, стол или стул? И 9 пунктов сравнения... Ну такое.

C++ даже в 2026-м году может работать без runtime, т.е. без stdlib++/STL и прочих Boost.
Даже exceptions можно из него выбросить прям на старте.
Можно полностью заменить new/delete, переделав их на старте на GC, ARC, или Arena Allocator и т.п. И это все равно будет C++. А STL это просто библиотека, не часть языка, хоть ее и пытаются позиционировать как неотделимую от языка, но это слава богу не так, пока ее еще можно полностью выбросить из зависимостей.

Подобная гибкость сразу дает недостижимые никому иному 100500 очков и ложит абсолютно всех на лопатки на старте, включая Swift, Kotlin и даже Rust.

C# - это просто yet another Java style Enterprise bloatware, в котором декларируется наличие библиотек для всего что угодно. А по сути эдакий 1C на супер-пупер стероидах. Но по факту там неизлечимая родовая травма - жестко вкодированный на системном уровне UTF-16. Ну и GC окончательно выводит его из технологического трека долгосрочной перспективы, т.к. GC в принципе не способен эффективно работать с кучами на десятки гигабайт, базы данных и ОС на нем точно никогда не написать. GC offheap - это костыль, а не решение. Веб странички, CRUD и простенькие UI - это да, но не более того. Даже Office на С# так и не смогли переписать, да и в самой Windows перешли на Webkit/Electron для UI, что уже говорит о многом. Плюс C# проприетарный и не true open source. И даже неповоротливую Java в которой до сих пор нет тех же properties - так и не смог победить, практически нигде.

Swift и тот смог уйти от UTF-16 и переехать на UTF-8, но не C#. C++ даже с STL в этом плане может в любые кодировки. Swift кстати, в сравнении со всеми остальными именно как язык на самом деле прям сильно хорош, и мог бы быть перспективным в целом, но в нем намертво прикручен ARC, что, увы, делает его тупиковым решением на длинной дистанции.

Так что альтернатив С++ нет (да и не было никогда).

Rust с его прям очень странными девиациями вроде "на объект может быть только одна мутабельная ссылка" выглядит скорее как агрессивно-религиозная секта пуританцев. А по факту уже 15 лет прошло, а даже coreutils толком не смогли на нем переписать, процесс все еще идет. Зато поломали вообще всем рендеринг True Type шрифтов (включая всех, которые на WebKit/Electron), других достижений и не вспомнить. Да и очень далеко не все готовы разделять подобную rust-аскезу, автор zig не даст соврать. Хайп вокруг Rust понятен, особенно подогретый уже недоступными ссылками "рекомендаций" АНБ, NASA и прочих White House, но на Silver buller он не тянет. Попытка заменить С++ по сути прогорела, если сразу не взлетело, сколько не рассказывай, что на C++ уже нельзя новые проекты открывать, но по факту на выходе получилась просто еще одна экосистема, в ряду Java, C#.NET, D, Go и прочих сообществ "С++ заменителей" появилось еще одно бесценное пополнение: Rust сообщество просто добавят своей энтропии с еще одной парой десятков невиданных реализаций веб серверов и JSON и YAML парсеров, которых к слову и под C++, и под C в избытке, а у HR-ов и PR-ов добавится головной боли на собеседованиях, так дальше все и поплывем в неведомые дали этого вашего энтерпрайз кодирования очередных CRUD UI.

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

И, кстати, причина этого превращения, как мне кажется, вовсе не в оптимизации и повышении надёжности, а в том, что последние десятилетия в C++ разработку приходят молодые PHP-кодеры, которые не учились думать категориями исполняемого кода. Ведь, на самом деле, C пришел на смену Ассемблеров и явился реально прорывом в технологии, хотя в то время уже существовали и Бэйсик, и Кобол, и прочие т.н. языки высокого уровня.

Я как раз таки пишу код без runtime и без STL под микроконтроллеры и микропроцессоры (Cortex-A, Cortex-R). Для этого подходит ровно 3 языка: С, С++ и Rust.

Так вот, найти нужную библиотеку на С++ без STL, а уж тем более без рантайма, не представляется возможным. Чаще всего нужно сериализацию/десериализацию, какое-нибудь шифрование, консольная графика и lock-free алггоритмы. Всё что существует в С++ требует кучу и рантайм.

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

На Rust огромный выбор, все в пакетном менеджере, и 1-2 строками в системе сборки включается no_std режим, и оно просто собирается и работает.

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

Статья, очевидно, шуточная.

Хотя поток возмущенных серьезных комментариев заставляет меня усомниться...

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

хочу объективно и беспристрастно ответить

8:1 в пользу C++

Не, ну тут конечно же все объективно и беспристрастно, он же смог найти минус в С++

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

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

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

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

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

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

Дискуссии конечно развернулись серьёзные!

Только изначально вы сравниваете 2 разных языка! При этом один (С#) был изначально написан на другом (на С++).

Потом, вы говорите про компиляторы, но какое они отношение имеют к языку? Это немного другая тема, потому как у разных сред разработки разные компиляторы, но одинаковые языки. Вы компиляторами сравниваете языки программирования... Серьёзно?

Дальше, С++ как база, применяется во многих других системах, отличных от прикладных задач (программирование микроконтроллеров, ПЛК, разработка новых языков программирования и т.д.) и для него не нужна никакая другая исполнительная среда, отладочная среда, framework. Ничего не нужно, только железо. В свою же очередь, С# не сможет работать без framework. Он работает в изолированной среде, в безопасной. Таким образом вы уже сравниваете 2 абсолютно разные системы/языки программирования.

И стоило тогда в статье упомянуть, о чем идёт речь (если только прикладные системы рассматриваются) и уточнять в чем их соавнивают, а не просто сравнивать их как языки программирования.

В целом было интересно почитать ещё и комментарии, потому как там самое развитие событий. И детали сравнили, и синтаксис и про .h файлы написали. Все мелочи обсудили, а глобально никто и не задумался, в чем же отличия!

Какой смысл сравнивать язык со сборщиком мусора и язык с прямым управлением памятью? У них же разные области применения!

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

Точнее, "язык с прямым любым управлением памятью ". Переопределение аллокаторов и операторов позволяет делать как угодно: стек, GC, RAII, арены итп

C++ плохой язык. Доказательством этого является то, что на нём пишут все меньше. С++ все ещё используется в тех нишах, где ему не придумали нормальные альтернативы.

Проекты высокого уровня пишут на языках со сборщиком мусора. Многие проекты низкого уровня выбирают чистый Си или же Rust.

На c++ очень медленная скорость разработки из-за отсутствия стандартизированного набора инструментов, ультра сложным подключением библиотек и слабой поддержкой IDE (проблемы всплывают с define и template).

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

Как правило c++ используется для узких месть, которые нужно ускорить, или же плотной интеграции с ОС. P-invoke позволяет делать это для C#, node-addons и wasm – для js.

Если говорить про тот же C#, то там есть много способов ускориться без p-invoke, например структуры, указатели и unsafe-код, System.Runtime.Intrinsics или те же Span.

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

Какое однобокое мышление. Видимо кроме прикладных вещей ничего другого и не делали.

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

Проекты высокого уровня пишут на языках со сборщиком мусора. Многие проекты низкого уровня выбирают чистый Си или же Rust.

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

Сами то писали на чистом С хоть раз? Вообще понимаете суть языка?

На c++ очень медленная скорость разработки из-за отсутствия стандартизированного набора инструментов, ультра сложным подключением библиотек и слабой поддержкой IDE (проблемы всплывают с define и template).

Очень странная логика! А если C# и С++ на одной IDE работают? Тоже все плохо? А медленной разработка может быть только по причине кривых рук и узкого лба, ну или когда человек изучил Python и возомнил себя невероятно гениальным программистом.

Как правило c++ используется для узких месть, которые нужно ускорить, или же плотной интеграции с ОС. P-invoke позволяет делать это для C#, node-addons и wasm – для js.

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

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

Какое однобокое мышление. Видимо кроме прикладных вещей ничего другого и не делали.

Однобокое мышление у тех, кто пишет только низкоуровневый код и ничего другого не знает.

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

C++ это база, потому что это более менее удачный язык, который первым занял нишу, но мы движемся вперед, сложность софта растет, парадигмы програмирования развиваются. Про “раскрутку компилятора” слышали? Если бы c++ был идеалом на нем так бы и писали.

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

Я ничего не приравнивал. Я просто знаю, что многие прошивки пишуться на Си. Си выбирают потому что уже есть примеры и тулчейн под Си, а для С++ нет, или например не хотят тащить в проект абстракции С++. Еще как оказалось на Си проще найти спецов чем на С++ и Rust. А если все звезды сходяться, специалисты находяться, тулчейны и библиотеки имеются, то тогда берут Rust. А еще, если надо взаимодействовать с ОС, то оказывается, что WinAPI прибито гвоздями к Си, Winrt к с++, а в macos к Objective-C/C++ и раст туда никак не вкрутить. Но если оказываться, что добрые люди написали нужные обертки, то раст становиться самым приоритетным выбором (опять же если команда умеет в него).

А если C# и С++ на одной IDE работают?

Я еще со времен Visual Studio 2005 заметил, что внезапно IntelliSense работает лучше на C# чем на С++. Время идет IDE прокачивается, но все равно C++ в этом плане отстает от C#, потому что DEFINE и TEMPLATE это просто подставление текста в шаблон. А у C# есть Generics, которые проще понимаются IDE.

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

Если в С++ нужно думать об высвобождении памяти, а в C# не нужно, то уже этого достаточно что бы считать что разработка на C# быстрее. Теперь сравните сколько времени надо убить на настройку CMake и MsBuild/Nuget? Вспомним что IDE хуже. А что насчет кучи строк каши в выводе компилятора, когда вы неправильно вызвали шаблон? А что насчет ошибок работы с памятью, вот на C# у нас вылетит exception мы видит стектрейс, а на с++ оно даже может не крашнуться и продолжить работу некорректно. Ах, я забыл, что я не отношусь к тем людям, кто пишет код сразу и без багов.

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

Python - это мусор, я не спорю. Зачем Python если есть божественный TypeScript и Bun.

Особенно смешно, как вы толкаете все в одну кучу про узкие места и интеграцию с ОС

Ну вот в моем мире, есть большая часть кода которую пишут на C#/JS и она работает отсилы 10% времени и маленькая часть кода на C++/Rust, которая работает 90% времени и в итоге мы приходим к компромиссу скорости разработки и ресуросоемкости приложения. А еще надо взаимодействовать с ОС, а API OC прикрученно к Си/ObjC/C++.

про js который к С++ не имеет вообще никакого отношения! Это разные вселенные!

Ну так и С# тогда тоже не имеет отношения, про что статья? Я вот прекрасно пишу node-addons и на C++ и на Rust, и даже было дело, что собирал объектный файл на Swift и линовал его к С++ коду. Но делал я это из нужды, потому что не мог вызвать API OC по-другому.

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

Помимо написания кода, а точнее войны с компилятором, есть еще вещи типа: алгоритмы, структуры данных, архитектура, базы данных, деплой, мониторинг. И вот я большую часть времени не пишу код, а генерирую его LLM занимаюсь побочными вещами, потому что написание кода это маленькая части работы. Когда я работаю с С++ написание кода это все мое время.

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

Очень жаль, что никто не говорит на латыни, это же база. А если серьезно, то да, С++ плохой, и понимание в чем он плохой делает меня сильнее. И поэтому, я избегаю его там где это возможно, а там где без него никак, пытаюсь понять спасет ли меня там Rust, и окончательно отчаевшишь иду выбирать между MinGW, MSVC и Clang.

Мдааа... Я же говорил немного о другом, к именно о том, что есть более широкий фронт применения языка программирования и он не ограничивается прикладным ПО. Вы же просто взяли и унизили язык программирования, который является основой и исходник ом для других. Кстати, латынь - никогда не была основой и базой, это параллельный язык для многих других. Ваше субъективное мнение складывается на ваших предпочтениях, и называть что-то плохим, если это не нравится вам - как минимум некорректно. Мне например не нравится бренд BMW, но это не делает его плохим, не смотря на сотни моих аргументов, почему он мне не нравится.

Вот вы мне привели массу аргументов с точки вашего зрения и разработки прикладных программ, а объективно и с точки зрения системного программирования - ни одного. Это ли не однобокое мышление?

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

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

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

И Rust плохой и другие тоже. Но поздравляю с 1м шагом к пониманию =)

Идеального языка нет. Тем более универсального

Раст, кстати, хуже многих, поскольку до сих пор не нашлось области применения, для которой он идеален.

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

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

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

Утверждение основано на моих ощущениях. Там кто-то внедряет на Rust (https://security.googleblog.com/2021/06/rustc-interop-in-android-platform.html), тут кто-то призывает отказаться от С++ (https://habr.com/ru/news/699142/). Объективных данных по языкам программирования мало. Надо парсить гитхаб, желательно самому гитхабу, что бы они захватили еще и приватные репо.

Итак, опрос StackOverflow, показывает что С++ вырос, но не на 3, а на 1-1,5% в зависимоти от категории, но там и Rust вырос, и С# и JS. Это ни о чем не говорит, тут задается вопрос о том, пользуются ли языками. Я пользуюсь С++, но большую часть времени пишу на TypeScript. В голосовании я бы поставил две галочки, но тут важен объем кода, а не просто изпользование языка. А таких данных нет.

Многие кто пишут на Rust, так или иначе касаются С/С++, потому что это же БАЗА. Безвыходная база, которую избегают если можно, но не всегда можно.

Что есть в поддержку моего утверждения? Например вот эта статистика, где показано количество новых репозиториев по основному языку: https://www.chartkite.com/github-archive Здесь отчетливо видно, как растет Rust по отношению к C++ и TypeScript по отношению к JavaScript. Там наверняка есть огромное влияние мусорных репозиториев, так как пришла эпоха LLM, но дефолтный язык для LLM это Python, вряд ли обыватель будет что-то вайбкодить на C++/Rust.

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

В частности, это не говорит о том, что популярность 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++ это язык с небезопасной памятью

Во-первых, нет такого понятия как "небезопасная память". Есть небезопасный доступ к памяти - выход за пределы массивов, трансмутация одних типов в другие, несинхронный доступ к общей памяти из разных потоков и прочее. Во-вторых у плюсов есть все инструменты для безопасной работы с памятью - умные указатели, всякие view-like объекты, алгоритмы, поддержка аллокаторов, немалое количество примитивов синхронизации и прочее. Оно не эргономичное, да, но определённо не отсутствующее.

Sign up to leave a comment.

Articles