Обновить
128K+
637
Sergei Kushnirenko@dalerank

Люблю (ш)кодить, алгоритмы и старые авто.

740,8
Рейтинг
1 144
Подписчики
Отправить сообщение

да можно и без ADL https://habr.com/ru/articles/762250/
private та еще дыра в языке PrivateMorozov, какойто Ж)

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

Как можно написать const T& и не знать про это

void foo(const T& x) { x.field = 5; }

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

rgba* get_rgba(const T& tx) { if (!tx.rgba) tx.load_rgba(); return tx.rgba; }

Текстура сюда const приходит? конст... а данные в ней не конст, она их загрузит на первом обращении. Это легально и это работает уже десятки лет, get_rgba принимает const T& пишет он в mutable-поле, а вызывается на объекте, который сам по себе изменяемый, хотя и помечен конст и с точки зрения системы типов не нарушено ничего.

А теперь в проекте появляются текстуры, которые константны по-настоящему, потому что видеокарта пометила их страницу как read-only. И тут нам очень бы хотелось, чтобы get_rgba их отличал, и для такой текстуры вызывать load_rgba() нельзя, там запись полетит в защищённую страницу. Но только отличить не выйдет, в шаблоне const T& один const уже потрачен на сам шаблон ибо мы думали про работу со ссылкой, и второй const аргумента ему просто некуда записать, он совпадает с шаблонным и был сьеден, а T вышел чистым. Из реального const T, он стал просто T и передавая его дальше по флоу, вы эту информацию потеряли.

template <typename T>
rgba* get_rgba(T& tx) {
    if constexpr (std::is_const_v<std::remove_reference_t<T>>) {
        // настоящая read-only текстура, её грузить нельзя, только читать готовое
        verify_crash(tx.has_pixels() && "read-only texture accessed before upload");
        return tx.pixels;
    } else {
        if (!tx.has_pixels())
            tx.load_rgba();
        return tx.pixels;
    }
}

Вот и получается, что если вы в шаблоне написал const T& то получили логику "принимаю всё, что const-совместимо, и забываю, если пришёл const const T&"

Технически верно, я об этом написал, шаблон этот баг не создаёт, он в принципе не про шаблоны и дыра целиком на совести const& + mutable. Но статья не о том, что шаблоны опасны сами по себе, но что вывод типов через шаблон меняет, как читается const T& и разработчик перестаёт держать в голове вопрос “а что мне реально прилетело”.

Обычная функция с явной сигнатурой const GruMemory& тот же баг пропустит, но сигнатура написана руками и типы видны сразу и шанс заметить проблему на кодревью выше. Шаблон здесь выступает усилителем непрозрачности. Если там сделать T& то мы можем внутри проверять конст объект пришел или не конст, а с концептами и вовсе запретить такие подлые функции

https://godbolt.org/z/qY7xjhfxK

template <typename T> requires (!std::is_const_v<T>)
auto& get_cache(T& obj) { ... }

мои недавние проекты говорят обратное, https://youtu.be/Tt1CYGt2goo?si=rAqiWGyzgfkdSJDi
клод действительно хорош в написании нового кода, возможно, но не в оптимизации уже существующего, особенно если это связано с памятью. Надеюсь мне дадут апрув на статью про это и можно будет показать, что ИИ не видит в упор

ну почему же, я только таких и встречаю "сделай збс" разве не ясное и точное объянение?

типичных для человека нет, новых аишных увидим вагон и пару прицепов

где-то я даже термин слышал про обесценивание труда разработчика, называется "пролетаризация программиста". Если будет время почитайте "Конец радуг", там как раз об этом рассказывается на примере главного героя, чьё прежнее мастерство исчезло (гениальность поэта не вернулась вместе с вылеченной памятью), и ему приходсятся заново собирать смысл жизни и творчество в перекроенном мире, садясь за парту рядом с подростками. Там правда про поэта, а не программиста, но очень близко... он умел то, что не умели большинство вокруг, а теперь это умеют все, пусть и не так хорошо.

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

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

200 мест использования строчек это действительно очень мало, вам и PGO не нужен, видимо игра очень маленькая. Для понимания о чем я тут вообще говорил, я бы посоветовал для начала подключить Tracy (это не сложно) и собрать его в режиме трекинга памяти, и посмотреть что происходит за 10 секунд игрового времени с системой.

Я наткнулся в рабочем чате на обсуждение известных старых багов в играх, вспомнил пару известных мне, потом пошел копать в интернетах чего там еще было, нарыл еще штук пять, потом набрел на статьи Шеффилда, а часть историй уже была у меня в записях, потом вспомнил про советско-российский игрострой. Ну вот как-то так и набралось, решил что указать Шеффилда и источники будет правильно.

Если я правильно помню статью на хабре, https://habr.com/ru/companies/ruvds/articles/889414/то в "ну, погоди" использовался КБ1013ВК1, аналог японского SM-5A. Аналог был на уровне программной модели, с 4 битами данных, набором портов ввода-вывода и сегментной логикой экрана. И если я правильно прочитал статью, то совместимость была на уровне машинных кодов, т.е. одна игровая логика исполнялась и для волка и микки.

Даже на парочку будет ;) что-то можно тут прочитать https://tproger.ru/articles/developers-tricks-in-games

так исторически сложилось

Речь в тексте шла о качестве кодовой базы и о том, что грязный код не помешал Minecraft стать самой продаваемой игрой. При чём тут "подход вокселей" мне не очень понятно, это спор с тезисом, которого в статье не было.

Если у Вас есть конкретный пример "геймдева снизу вверх", которого, по-вашему, тут не хватает, приведите его, разберём.

Первый программист пишет то, что решает задачу конечного пользователя: бизнес-логику, приложения, код поверх движка. Второй пишет то, на чём это работает: ОС, драйверы, компиляторы, рантаймы, сам движок. Вот только у второго тоже есть пользователь, и это первый. Так кто из них прикладнее?

Data-driven, когда поведение и структура игровых объектов описываются не в коде, а во внешних объектах текстовых или бинарных.
Префаб (prefab, prefabricated, predefined factory object) это заранее собранный "шаблон/заготовка" игрового объекта, со всеми или частью компонентов, готовый как-то создать, не обязательно это объект сцены, может быть все что угодно.
Энтитя (Entity) - некоторая сущность игрового движка, обычно созданная в сцене
VDF (Valve Data Format) key-value формат Valve для их движков

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

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

со временем видимо натащили фичей и сломали, такова судьба любого долгого проекта, в 2016 году на iPhone6s все бегало в 60фпс с запасом

1
23 ...

Информация

В рейтинге
1-й
Откуда
Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Десктоп разработчик, Разработчик игр
Старший
От 300 000 ₽
Git
C++
Многопоточность
Прикладная математика
ООП