Вот к чему тут реально можно прицепиться по технике, а не по вкусовщине.
1. Про constexpr аргумент сформулирован криво
Проблема в том, что это не контраргумент против constexpr как языка/абстракции.
Почему:
- constexpr гарантирует возможность вычисления на этапе компиляции, а не конкретную форму машинного кода.
- Будет imm, загрузка из .rdata, константная пропагация, инлайнинг или вообще удаление — это уже вопрос оптимизатора, ABI, ODR-use, отладочной/релизной сборки, взятия адреса и контекста использования.
- То же самое может происходить и не только с constexpr, а вообще с любыми константными объектами.
То есть доебка тут такая:
он подменяет тезис. Ему говорят про
типизацию, области видимости и compile-time validation, а он отвечает про
частный кодген.
Еще и формулировка:
Это технически грязно. Тут не “check”, а
load/read from memory. “Чек в память” — бессмысленный жаргон.
2. constexpr не равен “всегда быстрее” — но и критика у него слишком тупая
Если хочется добить сильнее, можно сказать:
- да, constexpr не гарантирует лучший кодген;
- но из этого не следует, что он плох или бесполезен;
- его ценность — в семантике, а не только в микрооптимизации.
То есть он спорит так, будто единственный критерий — “imm в асме”.
3. Про std::optional он пишет почти мимо
Это слабое место.
optional — не просто сахар, потому что он:
- делает “значение может отсутствовать” частью типа;
- убирает необходимость кодировать отсутствие через sentinel (0, -1, nullptr, false);
- снижает риск перепутать “валидное значение” и “признак отсутствия”;
- улучшает интерфейс функции и читаемость call site.
То есть это не только синтаксис, это
явная модель состояния.
4. Аргумент про размер/ABI у optional подан очень неаккуратно
Тут сразу несколько дыр:
- на x86-64 возвращаемый регистр обычно rax, а не ax, если речь не про какие-то частные мелкие типы;
- размер optional<T> зависит от T, выравнивания, ABI и реализации стандартной библиотеки;
- не факт, что речь вообще пойдет “про стек”;
- не факт, что sentinel-вариант реально дешевле после оптимизаций;
- optional<T*> и nullptr — отдельный кейс, и тут критика может быть частично справедлива, но не в такой общей форме.
То есть он бросает низкоуровневую претензию, но сам пишет ее технически неточно.
5. “std::variant: тоже самое” — это просто халтура
variant — не “то же самое”, что union.
Разница фундаментальная:
- union сам по себе не отслеживает активный альтернативный тип;
- у variant есть tag/index активной альтернативы;
- variant корректно управляет lifetime сложных типов;
- variant безопаснее и выражает сумму типов на уровне интерфейса.
Да, можно сказать:
- у variant есть overhead на discriminator;
- он тяжелее простого union;
- в hot path не всегда желателен.
Но писать “то же самое” — это просто технически неверно.
6. Про ranges аргумент почти пустой
Доебка здесь такая:
- “скомпилируется в тот же асм” — не универсально верно;
- иногда да, иногда нет;
- зависит от конкретных адаптеров, view chain, inlining, оптимизаций, категории итераторов и компилятора.
То есть утверждение слишком абсолютное.
А еще:
И что?
for и while на таком уровне — это почти одно и то же. Это не критика, а просто пересказ тривиального lowering.
7. Пример с for (x=y;x ? s; x(+-*=);) выглядит как техническая каша
Если хочешь прям придраться по форме:
- условие x ? s написано как какой-то обломок тернарного оператора;
- x(+-*=); вообще выглядит как псевдокод/бред;
- как “ассемблерно мыслящий технарь” он должен был хотя бы записать нормальную форму цикла.
То есть он пытается говорить низкоуровнево, но даже псевдокод оформляет неряшливо.
8. “STL скрывает реализацию, значит хуже” — слишком общий тезис
Здесь можно нормально вцепиться:
- “не всегда оптимальна” — банальность, это почти про любой код;
- “без STL где возможно” — плохая инженерная эвристика;
- сначала нужен профилинг, а не религия;
- STL часто компилируется очень хорошо, особенно простые контейнеры/алгоритмы/итераторы;
- самописные структуры данных часто дают больше багов, чем выигрыша.
Хорошая доебка:
он подает
ручной low-level код как дефолт, хотя это оправдано только после измерений.
9. “всё это сахар” — сильное упрощение до неправды
Сводить optional, variant, constexpr, ranges к “сахару” некорректно.
Из перечисленного:
- optional — это модель optional-state в типе;
- variant — tagged union;
- constexpr — compile-time semantics;
- ranges/views — композиционная модель работы с последовательностями.
Это не просто синтаксический декор.
10. “любой view unsafe априори” — откровенно плохой тезис
Вот тут можно прям жестко доебаться.
Это слишком грубое и часто ложное утверждение.
Почему:
- не любой view опасен;
- danger zone — это в основном lifetime issues, dangling, non-owning semantics;
- часть view безопасна при нормальном использовании;
- в стандартной библиотеке есть понятия вроде borrowed_range, а многие проблемы вообще типичны не только для view, но и для span, string_view, итераторов, ссылок и т.д.
Фраза
звучит как человек знает слово “dangling”, но не умеет различать
условно опасный инструмент и
априори unsafe сущность.
11. Он смешивает разные уровни разговора
Исходный пост, судя по цитатам, про:
- качество интерфейсов,
- читаемость,
- безопасность,
- уменьшение числа багов.
А ответ уходит в:
- .rdata,
- imm,
- размер на стеке,
- runtime overhead.
То есть он спорит не с тем тезисом:
- на аргумент про maintainability отвечает аргументом про микрооптимизацию;
- на аргумент про безопасность типов отвечает “ну это сахар”.
Это логически слабая линия.
12. У него нет границ применимости
Нормальный техничный тезис выглядел бы так:
- в hot path / perf-critical коде некоторые абстракции стоит проверять профилингом;
- optional/variant/ranges могут давать overhead в отдельных сценариях;
- для game hacking / cheat runtime / tight loops иногда оправдан ручной контроль layout и lifetime.
Но он пишет это как
общее правило, а не как
узкий trade-off.
Это делает текст уязвимым.
Если собрать самую убойную короткую выжимку, то доебаться можно так:
Могу еще сделать тебе версию
в стиле форумного разъёба, чтобы это можно было сразу запостить ответом.