суббота, 12 июля 2025 г.

[prog.c++] Примеры нововведений в С++, которые "осчастливили" меня (на самом деле нет)

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

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

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

Ладно, хватит предисловий, двайте начнем.


std::launder. Очень специфическая штука, которую мало кто понимает. И, что раздражает больше всего, ведь до введения std::launder в стандарт код у людей работал. И сейчас у многих работает. Но может внезапно перестать. При этом если опросить 1000 случайных C++ разработчиков, то, боюсь, малый процент из них вообще сможет внятно рассказать для чего std::launder в принципе нужен. И еще меньший процент сможет объяснить где же std::launder должен применяться, а где нет.

При этом std::launder имеет отношение к такой штуке как lifetime, но когда вводили std::launder почему-то не включили в стандарт никаких других инструментов для объявления начала lifetime в остальных случаях, не покрываемых std::launder. Например, абсолютно необходимая во многих ситуациях std::start_lifetime_as была добавлена только в C++23. При том, что многие проекты все еще на С++17 и непонятно когда на C++23 смогут перейти.

Т.е. в C++17 разработчиков поставили перед фактом о том, что теперь компилятор может начать эксплуатировать UB, связанные с lifetime-ами. И лишь в C++23 программистам дали нормальный набор инструментов.

При этом в C++20 сделали некую полумеру -- объявили набор магических функций и ситуаций, когда lifetime неявно начинается. Типа std::malloc начинает lifetime, а какая-то произвольная пользовательская функция, скажем, my::shared_memory_arena::malloc -- нет, потому что стандарт про нее не знает, и стандарт не дает никаких возможностей указать, что пользовательская функция ведет себя как malloc.

Если смотреть на всю эту эпопею с std::launder в C++17, implicit lifetimes в C++20 и std::start_lifetime_as в C++23, то складывается ощущение, что люди из комитета тупо затыкали дыры по мере их обнаружения. Вместо того, чтобы провести глубокий анализ и выкатить полноценное решение, а не набор отдельных "заплаток", да еще и растянутых на период в шесть лет.

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


Модули.

Тут мне вообще сложно говорить цензурно.

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

Кроме того, есть у меня ощущение, что модули не дадут заметного положительного эффекта в случаях, когда в коде используется много шаблонов. Ибо когда сейчас имеешь дело с таким кодом, то даже невооруженным взглядом видно, что основное время тратится не на парсинг C++ного кода, а на инстанцирование шаблонов и их оптимизацию. Т.е. если у меня сейчас .cpp-файл транслируется 20 секунд, включая все include и пр. расходы от которых типа должны освободить модули, то с модулями этот файл будет транслироваться 19 или, если поведет, 18 секунд. Отличное достижение, прям таки победа.

Может быть какой-то выигрыш от модулей был заметен в 2019-ом на тогдашних CPU и HDD-дисках. Сейчас, когда даже в бюджетных ноутбуках стоят CPU с десятком(!) ядер и SSD со скоростями больше нескольких гигабайт в секунду, проблем с длительной обработкой большого количества include нет от слова совсем.

Ну и главное: сейчас уже середина 2025-го года, а нормальной полноценной поддержки модулей в большой тройке компиляторов нет.

И спрашивается: а оно вообще стоило того? Угробить кучу ресурсов на внедрение в стандарт, компиляторы, IDE и пр. инструменты поддержку явно переусложненной системы модулей, которая вносит в C++ такой же раскол, как Python3 по отношению к Python2. И не получить вменяемого результата даже через пять лет после выхода С++20.

Это, блин, полный успех.

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


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

Что меня раздражает в deducing this больше всего, так это не то, что в C++ добавили очередной всратый синтаксис для того, чтобы сделать тоже самое, но совсем другим способом, а то, что deducing this вообще не дружит с DLL/SO библиотеками.

Вот хотите вы экспортировать из DLL/SO свой C++ный класс. И в этом классе есть дублирующиеся методы, количество которых хотелось бы подсократить посредством deducing this. Но вы этого не сможете, потому что deducing this работает по принципу C++ных шаблонов.

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

Идиотия чистой воды. Но, видимо, кто с Python-измом или Rust-оизмом головного мозга очень хотел превратить C++ в подобие Python/Rust с явной передачей self-а в методы класса. И у этого "кого-то", что характерно, получилось 🙁


Включенная в C++26 рефлексия времени компиляции.

Тут я нахожусь в полной растерянности от выбранного синтаксиса.

Во-первых, каким боком ^^ к рефлексии? Ведь в C++ есть оператор ^, как этот оператор соотносится с рефлексией? Никак? Здесь нет логики, нужно просто запомнить, что ^ -- это про операции над битами (если он не перегружен, конечно), а ^^ -- это рефлексия? Ну так чем ^^ лучше любого другого единичного символа? Почему ^^T, а не @T или %T или даже `T?

Во-вторых, почему "операторные скобки" для рефлексии используют двоеточие? Оно же тупо плохо заметно в тексте в комбинациях [: и :]. И, кроме того, оно вообще никак не соотносится с ^^.

Т.е. нужно просто зазубрить, что получить метаинформацию -- это ^^, а использовать метаинформацию -- это через квадратные скобки с двоеточием.

Логично и последовательно, да.


В общем, что хочу сказать в завершение...

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

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

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

Ну и да, комитету насрать на то, когда приятое им в стандарт появится в большинстве компиляторов в приемлемом качестве. Поэтому давайте штамповать фичи, которые доберутся до рядового разработчика через 5-6-7 лет. А то и не доберутся вовсе, как export template из С++98. Пофиг, пипл схавает.

Поэтому еще раз повторю то, что уже писал в разных соцсетях:

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