Я почти 20 лет пишу код на С++ за деньги, и почти все это время ощущаю неприязнь к инструменту, который позволяет мне безбедно жить. К тому же я занимаюсь системным программированием, а это налагает дополнительные требования к знанию языка.
Я долго не мог выразить вербально, что меня так отталкивает в C++. Однажды из любопытства меня заинтересовал Rust. Я влюбился в него не сразу, сделав не менее 3х подходов к снаряду изучению, пока наконец-то не нащупал интуитивное понимание. С этого момента Rust превратился для меня в эталон инструмента для системного программирования.
Так что и где не так?
Отношение к Rust делит людей на два полярных лагеря: одни его любят за его явные преимущества, другие - беспричинно ненавидят.
Я всегда пытался понять истинный мотив этой ненависти, потому что люди часто сами не могут осознать свои чувства. Это особенно относится к программистам, замкнутым по своей природе.
Я также пытался проанализировать свою неприязнь к C++. Заодно пытался поставить себя на место хейтеров Rust и понять их мотивацию. Это долго не получалось, но вдруг...
Картинка сложилась
Для меня C++ является языком, требующим колоссального внимания в силу неимоверного количества правил, исключений и просто абсолютно нелепых конструкций с точки зрения языкостроения.
Я сейчас даже не говорю о тяжелом наследии C, достаточно одной такой вещи современного C++: стандартизационный комитет придумал семантику перемещения и ввел в язык, помимо физического use-after-free, еще и логический use-after-free, возникающий в результате доступа к объекту, из которого выполнено перемещение. Думаю, понятно, что подобного и близко нет в Rust.
Почему воротнички
Так вот получается, что для овладения C++ вам нужны в первую очередь хорошая память и исключительная концентрация внимания. В противовес этому, Rust позволяет запомнить относительно небольшой набор аксиом и далее пользоваться правилами вывода для конструирования всех остальных утверждений языка. Это то, что делает язык логичным, ибо описанное напрямую подчиняется законам формальной логики.
А теперь посмотрите на это под таким углом: где у нас в жизни одним специалистам нужны память и внимание, а другим - логика? Так ведь ясно, что к первой группе относятся мастера, операторы станков и инструментов и прочие синие воротнички. А что со второй группой? Это инженеры, математики и люди подобных профессий - белые воротнички.
Именно поэтому одним разработчикам комфортна полная свобода C++ и не нравятся рамки Rust. Они просто любят полагаться на память и внимание, а не на логику. Я сейчас абсолютно серьезен: для меня написание кода на плюсах давно превратилось в постоянное подглядывание в http://en.cppreference.com/ по поводу и без, которое уже иногда напоминает паранойю. Я не умею запоминать, я умею понимать. Rust для меня интуитивно понятен и прост, а C++ - неинтуитивно сложен и утомителен.
Заключение
Когда я это понял, не произошло ничего особенного. Мир остался прежним, я тоже остался прежним. Просто я осознал, почему мой выбор — правильный для меня. И почему он, конечно, не подойдет всем.
Поэтому когда вам в очередной раз доведется слышать стандартный спор C++ vs Rust, вспомните эту заметку и определите для себя: вы либо синий воротничок, либо — белый. И когда напротив вас появляется человек другой окраски воротничка — перестаньте напрягаться. Диалога все равно, скорее всего, не выйдет.
Комментарии (17)

8street
16.12.2025 05:13Для меня C++ является языком, требующим колоссального внимания в силу неимоверного количества правил, исключений и просто абсолютно нелепых конструкций с точки зрения языкостроения.
C++ хорош тем, что можно не использовать все навороты языка одновременно. Какой-нибудь один гайд-стайл себе выбрать (а зачастую он уже наработан в проекте) и писать только на нем.

apevzner
16.12.2025 05:13C++ хорош тем, что можно не использовать все навороты языка одновременно
Это соображение хорошо работает, когда ведёшь проект в одиночку, или в команде принята дисциплина и единомыслие. И когда большая часть кода - своя, и не состоит в основном из legacy, авторы которого оставили свой неповторимый стиль в коде прежде, чем окончательно исчезнуть с радаров.
В реальности чаще получается ограничивать себя, но не соседа/соседний отдел/авторов библиотеки с гитхаба, которую вам посчастливилось использовать в проекте.

eao197
16.12.2025 05:13В реальности чаще получается ограничивать себя
Оно бы звучало весомо... Только вот это говорит человек, который пишет на чистом Си и go, а не на C++ (и даже толком не знает C++, что уже неоднократно было продемонстрировано на RSDN).
В C++ гораздо чаще приходится ограничивать себя тем, что есть в компиляторах.

apevzner
16.12.2025 05:13В C++ гораздо чаще приходится ограничивать себя тем, что есть в компиляторах.
Я примерно про это и говорю. Угу, тем, что есть в компиляторах...

eao197
16.12.2025 05:13Только вот это принципиально отличается от высказанного выше:
Какой-нибудь один гайд-стайл себе выбрать (а зачастую он уже наработан в проекте) и писать только на нем.
Здесь тов. @8street наверняка говорил о фичах языка, которые выбираются (или отвергаются) безоностительно возможностей компилятора. И у которых, по хорошему, должна быть мотивация из категории "потому что". Например, запрет на использование исключений потому что real-time или низкоуровневый код драйвера. Или запрет на использование RTTI потому что в итоговом исполняемом файле остается слишком много информации об исходном коде. Или запрет на использование unified initialization syntax потому что запись
v{x, y}будет вести себя неожиданным образом, еслиv-- этоstd::vectorилиstd::string.Как правило, такие рекомендации формируют подмножество языка, работа с которым не должна вызывать проблем (как у команды разработки, так и при эксплуатации).

AlexGorky
16.12.2025 05:13"Не путайте туризм с иммиграцией".
Возможно, если начнёте писать на Rust за деньги, и его тоже возненавидите ))
Сходу вот нашёл чью-то боль и вот и вот.
Претензии - медленная компиляция, сложный для понимания синтаксис (например "Pin<Pin<&dyn LocalTrait>>") и т.п.
Вообще со временем начинаешь понимать, что нет идеального языка.

MinimumLaw
16.12.2025 05:13Отношение к Rust делит людей на два полярных лагеря: одни его любят за его явные преимущества, другие - беспричинно ненавидят.
Ох не люблю я эти темы... Вы говорите "К тому же я занимаюсь системным программированием, а это налагает дополнительные требования к знанию языка."
Проблема ровно в том, что у меня с вами очень разное понимание "системного программирования". В моем мире этим термином называют тот код, который НЕПОСРЕДСТВЕННО работает с аппаратурой (все эти DMA каналы, контроллеры прерываний, таймера, системные таблицы, регистры периферии и самого процессора). Этот код - фундамент. Соответственно, любой язык, который прячет от меня этот код для меня неприемлем. В частности C++. Для меня не очевидно как именно код на плюсах будет преобразован в ассемблер, и как итоговый код будет меняться в зависимости от ключей оптимизации или используемого компилятора. Лучший вариант - ассемблер. Самый разумный компромисс - С (без всяких плюсов). Все, что описываете вы работает на уровне выше. Для меня это частный случай прикладного ПО. И да, я не очень понимаю как делить его на уровни.
А еще, чисто для аналогии, есть вполне традиционный подход в современном загородном строительстве. Перезаклад на фундамент. Его делают заведомо сильно более мощным, чем требуется. Rust - эти аналог такого подхода, перенесенный в мир вычислительной техники. В подавляющем большинстве случаев это работает. Хоть и стоит значительно дороже. И в этом смысле нет проблем - пусть будет Rust. Но как в строительстве остается спрос на фундаменты без перезаклада, так и здесь разного уровня ассемблеры, скорее всего, никуда не денутся. Не всех устроит тот самый перезаклад. Более того, в строительстве уже активно отходят от такого подхода. Ибо у него уже находятся объективные изъяны. Например повышенная усадка или разломы из-за увеличившейся массы, или повышенные требования к качеству материалов. И это не считая главного - цены вопроса. Лично у меня нет сомнений в том, что рано или поздно и с Rust будет ровно то же. Это довольно молодой язык. Но молодость проходит. Наивно полагать, что Rust останется "вечно молодым". С доказал, что умеет взрослеть и красиво стареть. Впрочем, помирать он пока не собирается. Более того - пока молодые у него учатся. И это хорошо.

apevzner
16.12.2025 05:13Проблема ровно в том, что у меня с вами очень разное понимание "системного программирования". В моем мире этим термином называют тот код, который НЕПОСРЕДСТВЕННО работает с аппаратурой
Я тоже работаю с аппаратурой, но только в последние несколько лет моя аппаратура - это принтеры и сканеры. Это такие довольно сложные железки, которые разговаривают с хостом в основном по сети или по USB.
Желание иметь 100% видимость и контроль на стыке железа и софта очень понятно. Непонятно, зачем для этого ассемблер. В целом, компилятору можно доверять, обычно всё же он нагенерирует то, что написано (в рамках свобод, гарантированных ему спецификацией языка). Мешают библиотечные автоматизмы, которые могут влиять на семантику действий.
В этом плане Go, например - вполне годный язык. Потому что от него можно добиться того, чтобы памятью он управлял, а в протокольные дела не лез, оставив видимость и контроль, сравнимые с ANSI C. Да, времянку он не всегда гарантирует, но мои устройства не настолько чувствительны к времянке.

MinimumLaw
16.12.2025 05:13Для принтеров и сканеров, драйвера которых по сути фильтры - это допустимо. Для драйвера, скажем, сетевой или аудио карты - уже сложнее. В этом случае работает "доверяй, но проверяй". И если то, что было написано на С я могу проверить, то с остальными языками сложнее. А вот, допустим, переключатель задач (именно переключатель, а не более обобщенный термин "планировщик") непосредственно на языках высокого уровня почти всегда не реализуем. И даже Rust здесь будет бессилен. Исключительно ассемблер.

apevzner
16.12.2025 05:13Для принтеров и сканеров, драйвера которых по сути фильтры - это допустимо
В некотором идеальном мире драйвера принтеров (но не сканеров) - это фильтры, которые преобразуют условный PostScript в условный URF или PWG-Raster.
В реальном мире там достаточно возни вокруг затыков аппаратуры. Причём понятие аппаратуры включает в себя заглюки firmware, которое там сложное и хрупкое. И там всё, как у людей (у прочих железок). Например, пока принтер "прогревается", он может весьма своеобразно реагировать на стандартные запросы.
Я писал драйвера сетевых карт, в т.ч, и Wi-Fi, с достаточно сложной логикой на хосте. Мне эта тема вполне знакома.
Переключатель задач на С я тоже, кстати, писал :)

MinimumLaw
16.12.2025 05:13То, что я самостоятельно менял сцепление, пружины и амортизаторы на своем авто не делает меня автомехаником. И даже ежегодное перекидывание колес этому никак не помогает. Как и опыт ремонта головки блока цилиндров с заменой и притиркой клапанов. В лучшем случае я что-то понимаю. Но не больше.

apevzner
16.12.2025 05:13Сколько драйверов надо написать, чтобы из автолюбителя превратиться в автомеханика? :)

MinimumLaw
16.12.2025 05:13Достаточно ни одного - это очень разные специальности с очень разными инструментами. Даже если мультиметр электрика используется ими обоими. Между этими специальностями, безусловно, можно мигрировать. Но мастерство можно получить только с удовольствием занимаясь любой из них всю жизнь.

apevzner
16.12.2025 05:13Я всю жизнь с удовольствием занимаюсь системным программированием, в диапазоне от того, что делается с привлечением осциллографа и до весьма высокоуровневых вещей типа разборок с системой печати.
Желание слазить на уровень ассемблера пару раз присутствовало и ни разу в итоге не оправдывалось.
Я просто столяр-универсал, а не специалист по закручиванию шурупов определенного размера и с определенной формой шляпки в древесину определенного вида. Могу сделать полированный шкаф из морёного дуба, а могу - сосновый гроб.

eao197
16.12.2025 05:13Основной посыл статьи от меня ускользает. Кажется, что ключевое -- это:
Диалога все равно, скорее всего, не выйдет.
Но если диалога между растаманам и плюсо
дрочерфилами не выйдет, то зачем нужно было эту статью публиковать?
pavlushk0
"...логический use-after-free..." - простое правило, не обращайся к объекту в moved-from стейте (даже если очень хочется, и есть сто кейсов когда нужно и т.д и т.п.). Можно не использовать move вообще. Вообще можно не использовать вещи которые не нужны, а маргинального говна в c++ полно, хоть тоже виртуальное наследование.
"Я не умею запоминать, я умею понимать" - это норм, причём в отношении любого языка. Стоит понимать что к формированию C++ и его библиотек и компиляторов причясны тысячи человек на протяжении десятков лет, естествено что один человек не способен осознать весь этот корпус знаний.
Kelbon
То что автор назвал логическим use after free это буквально относится к любому обращению к переменной после её изменения. Например после swap или просто вы сделали clear на векторе и потом обратились к нему.
В общем претензия самая нелепая из всех что представители языка ада2 предъявляли С++