Прикол
Сидел значит в Rider, работал, скомпилировал код
Услышал в наушниках отчетливый звук из Анрила что код успешно скомпилировался
Смотрю на панель панель задач
А там нет открытого Анрила 💀
СлУхОвЫе ГаЛлЮцИнАцИи...
Сидел значит в Rider, работал, скомпилировал код
Услышал в наушниках отчетливый звук из Анрила что код успешно скомпилировался
Смотрю на панель панель задач
А там нет открытого Анрила 💀
СлУхОвЫе ГаЛлЮцИнАцИи...
❤3😁1
2 варианта записи одного и того же в C++
Вроде бы и там и там условие...
Вроде бы 2 похожих блока...
Вроде бы 2 функции вызываются...
...или нет?
Вроде бы и там и там условие...
Вроде бы 2 похожих блока...
Вроде бы 2 функции вызываются...
...или нет?
❤1🤯1💯1
𝐑𝐨𝐨𝐭𝐓𝐨𝐨𝐥 𝐁𝐥𝐨𝐠
2 варианта записи одного и того же в C++ Вроде бы и там и там условие... Вроде бы 2 похожих блока... Вроде бы 2 функции вызываются... ...или нет?
Как элегантный if ломает ноги персонажу
Казалось бы, переписал громоздкие переменные в красивое условие if(Left() || Right())
Меньше строк, код чище! Но персонаж начнет хромать. Почему?
Все из-за механизма short-circuit evaluation (короткое замыкание) в С++ (который плотно отражен в ассемблере)
Компилятор просто экономит такты процессора: если в условии
Но мы забыли, что наши функции - пишут данные по ссылке внутри ([&] DistanceRight)
В итоге получаем красивый баг:
- Мы создали 2 float переменных, но не проинициализировали их (в них может быть мусор, космическое число, и тд.)
- Левое условие выполнилось, записало результат в переменную, и вернула true
- Компилятор радостно прыгает внутрь if, скипнув вызов для правого условия...
- И в DistanceRight остаётся лежать мусор из стека!
- Из-за чего математика в FMath::Max() начнет честно сравнивать левое значение с мусором... и персонаж будет улетать в стратосферу
Мораль сей басни такова
Красивый код - это круто, но side-эффекты внутри ленивых || и && - это классический выстрел в ногу. В буквальном смысле - правую ankle_r
Казалось бы, переписал громоздкие переменные в красивое условие if(Left() || Right())
Меньше строк, код чище! Но персонаж начнет хромать. Почему?
Все из-за механизма short-circuit evaluation (короткое замыкание) в С++ (который плотно отражен в ассемблере)
Компилятор просто экономит такты процессора: если в условии
A || B левое условие выполнилось A = true, то результат всего true || B уже и так ясен - и выполнять правый блок B просто не имеет смыслаНо мы забыли, что наши функции - пишут данные по ссылке внутри ([&] DistanceRight)
В итоге получаем красивый баг:
- Мы создали 2 float переменных, но не проинициализировали их (в них может быть мусор, космическое число, и тд.)
- Левое условие выполнилось, записало результат в переменную, и вернула true
- Компилятор радостно прыгает внутрь if, скипнув вызов для правого условия...
- И в DistanceRight остаётся лежать мусор из стека!
- Из-за чего математика в FMath::Max() начнет честно сравнивать левое значение с мусором... и персонаж будет улетать в стратосферу
Мораль сей басни такова
Красивый код - это круто, но side-эффекты внутри ленивых || и && - это классический выстрел в ногу. В буквальном смысле - правую ankle_r
❤1🔥1
Интересный факт
Читая на завтрак исходники Unreal Engine, заметил что в откровенных комментариях в коде движка такие слова как
А на втором месте, как ни странно - низкоуровневый код работы с памятью (контейнеры, аллокаторы, специфичный код на каждое железо, и тд.)
Заметьте: Больше всего боли в рендеринге, и менеджементе памяти
Я конечно ни на что не намекаю.... но думаю вы, двиглоделы, понимаете в каких местах нужно закупаться побольше магнием
Читая на завтрак исходники Unreal Engine, заметил что в откровенных комментариях в коде движка такие слова как
fuck, shit, stupid, harm, pain, tired и даже табуированное suicide, чаще всего появляются в модулях связанных с рендерингом в UEА на втором месте, как ни странно - низкоуровневый код работы с памятью (контейнеры, аллокаторы, специфичный код на каждое железо, и тд.)
Заметьте: Больше всего боли в рендеринге, и менеджементе памяти
Я конечно ни на что не намекаю.... но думаю вы, двиглоделы, понимаете в каких местах нужно закупаться побольше магнием
🙏1👀1
НИКОГДА НЕ СОЗДАВАЙ АССЕТ С ИМЕНЕМ "DummyCookedFilename" В АНРИЛ ЭНДЖАЙН В 3 ЧАСА НОЧИ
Причина? Прекрасные люди из прекрасной конторы, когда писали кукинг систему (времена UE3), была проблема - Кукинг система требует полный список файлов. А если заранее некоторые ассеты были запеченные в .pak файле, то открывать их ради списка - самоубийство
Тогда они решили - а давайте просто запеченные файлы для кукинг системы будем называть "DummyCookedFilename"?
Ну ля, молодцы, что сказать. Теперь если я подсуну кому-нибудь в проект ассет с таким названием, то при запаковке, ууу.....
Видите макрос
Причина? Прекрасные люди из прекрасной конторы, когда писали кукинг систему (времена UE3), была проблема - Кукинг система требует полный список файлов. А если заранее некоторые ассеты были запеченные в .pak файле, то открывать их ради списка - самоубийство
Тогда они решили - а давайте просто запеченные файлы для кукинг системы будем называть "DummyCookedFilename"?
Ну ля, молодцы, что сказать. Теперь если я подсуну кому-нибудь в проект ассет с таким названием, то при запаковке, ууу.....
Видите макрос
check? Вот он заставит упасть ваш движок, если кукинг система встретит ассет с таким названием. И даже ошибку толком не непишет. А отловить такое - хаха, ну удачи))❤🔥1🔥1😁1
"То что в ООП было Релизно, в ECS еще Дебаг"
Решил вечерком потыкать злополучный ECS и что могу сказать... мне нравится. Нет, мне правда нравится
Даже не то скорость, а само... ощущение. Ощущение снова чувствовать железо. Обычно я убегалв эскапизм тыкать AVR, ибо я любил ее из-за непередаваемого ощущения железа в руках
А сейчас... потыкав ECS, я испытал это же чувство! Когда нет виртуальных таблиц, лишних прыжков, аллокаций. Каждый байт жестко контролируешь именно ты. И это.... прекрасно
Кстати когда впервые запускал ECS то вспомнился клип: Can You Hear The Speed
Решил вечерком потыкать злополучный ECS и что могу сказать... мне нравится. Нет, мне правда нравится
Даже не то скорость, а само... ощущение. Ощущение снова чувствовать железо. Обычно я убегал
А сейчас... потыкав ECS, я испытал это же чувство! Когда нет виртуальных таблиц, лишних прыжков, аллокаций. Каждый байт жестко контролируешь именно ты. И это.... прекрасно
Кстати когда впервые запускал ECS то вспомнился клип: Can You Hear The Speed
❤1💯1
Епрст. Пока писал компилятор, буквально ОСОЗНАЛ одну историческую штуку из C
В общем, помните из C этот странный синтаксис?
Но почему в скобках в foo мы пишем (void)?
Конечно, официально говорят, чтобы функция принимала 0 аргументов
Но пока писал однопроходный компилятор, заметил 1 штуку: Вот читаю я посимвольно... Увидел foo, увидел скобку, как мне понять что функция объявляется или вызывается, не заглядывая в аргументы? (так как компилятор однопроходный)
Правильно: Проверить после скобки, что там? Если
Но что если.... у меня 0 аргументов? Если у меня
В общем, ясно одно: Если тебе кажется что в C эта вещь бесполезна, значит ты не понимаешь зачем эта вещь вообще нужна
В общем, помните из C этот странный синтаксис?
void foo(void) {
// ....
}
foo();Но почему в скобках в foo мы пишем (void)?
Конечно, официально говорят, чтобы функция принимала 0 аргументов
Но пока писал однопроходный компилятор, заметил 1 штуку: Вот читаю я посимвольно... Увидел foo, увидел скобку, как мне понять что функция объявляется или вызывается, не заглядывая в аргументы? (так как компилятор однопроходный)
Правильно: Проверить после скобки, что там? Если
int - значит дальше мы встретим переменные, значит, объявляем функцию. А если не так - (если просто переменная или число) - вызываем эту функциюНо что если.... у меня 0 аргументов? Если у меня
()? Как мне понять где объявление, а где вызов? Ха, правильно - поставить (void)!В общем, ясно одно: Если тебе кажется что в C эта вещь бесполезна, значит ты не понимаешь зачем эта вещь вообще нужна
❤1💯1
𝐑𝐨𝐨𝐭𝐓𝐨𝐨𝐥 𝐁𝐥𝐨𝐠
Почему в час ночи вместо работы в UE я должен разбираться почему он падает нафиг И сюрприз сюрприз - падает из-за Race Condition в сборщике мусора (на скрине FGCReferenceTokenStream и UGCObjectReferencer) Когда объект еще не успел удалиться и сборщик мусора…
Помните как у меня слетал GC Анрила из-за поломки vtable?
Так вот. Нашел я решение. почти...
Хорошие новости: Я смог увеличить время срабатывания GC до космических цифр, и теперь ближайшие 272 млрд лет он меня не потревожит
Плохие новости: Теперь память НЕ будет очищаться. И раз в час (наверное) у меня Анрил просто тупо будет лагать и вылетать из-за нехватки память
То есть буквально движок будет ходить под себя и захлебывается в собственным же дерьме
Лучший просто, братец Тим Суини, продолжай!
Так вот. Нашел я решение. почти...
Хорошие новости: Я смог увеличить время срабатывания GC до космических цифр, и теперь ближайшие 272 млрд лет он меня не потревожит
Плохие новости: Теперь память НЕ будет очищаться. И раз в час (наверное) у меня Анрил просто тупо будет лагать и вылетать из-за нехватки память
Лучший просто, братец Тим Суини, продолжай!
❤2🤣2❤🔥1👍1😁1👀1
void Subleq(int* Memory)
{
int PC = 0; // Program Counter
while(PC >= 0)
{
const int A = Memory[PC + 0];
const int B = Memory[PC + 1];
const int C = Memory[PC + 2];
memory[B] -= Memory[A];
if(Memory[B] <= 0) PC = C;
else PC += 3;
}
}
👀2
Нет, мне определенно надо ехать в казино
Чтобы вы понимали: Шанс поймать ICE (Internal Compiler Error) обычному рядовому программисту - менее 0.01%
Для embedded - уже чуть выше, но в пределах 1-2%
А я уже как второй день словил АЖ 2 ICE В ОДНОМ ПРОЕКТЕ СУКА
2 раза ломать компилятор от своего же кода - это определенно талант
Чтобы вы понимали: Шанс поймать ICE (Internal Compiler Error) обычному рядовому программисту - менее 0.01%
Для embedded - уже чуть выше, но в пределах 1-2%
А я уже как второй день словил АЖ 2 ICE В ОДНОМ ПРОЕКТЕ СУКА
2 раза ломать компилятор от своего же кода - это определенно талант
❤🔥5👻1
В общем, что-то лежал, рефлексировал, и подумал
А ведь действительно произошло то, что говорят "всё новое - хорошо забытое старое"
Вспомнил про новую технологию из UE5 под названием Nanite - когда мы берем меш, разбиваем его на кластеры по 64-128 полигонам, и нумеруем их по ID
А дальше просто из камеры, по каждому пикселю, пускаем луч. И если тот попал в полигон - записываем в специальный буфер (VisBuffer) ID Меша, Кластера и Полигона (а затем на втором рендер-пассе раскрашиваем/растеризуем их, но не суть)
К чему все это? Так к тому, что эти последовательные 2 шага.... Чертовски напоминают мне Wolfenstein 3D аж из 1992 года!
Ведь вспомните - тогда математика на процессорах была чертовски дорога. Проходиться циклом по каждой стенке/псевдо-полигону, проецировать его точки, считать матрицы, а потом еще закрашивать - непозволительная роскошь...
И тогда молодой Кармак придумал - а что если просто пускать луч из камеры, находить стену, расстояние до нее, и сразу же красить? Так и родился легендарный метод под названием "Рейкастинг"!
И в чем моя мысль: Если так посудить... Nanite - это идеальное продолжение идеи Кармака, возведенная в абсолют!
Вместо 2д лучей - 3д. А вместо прямого "сделал пересечение - покрасил" у нас сначала запоминание пересечений во временный буфер (VisBuffer), а уже затем - покраска по этому буферу
всё новое - хорошо забытое староe ;P
А ведь действительно произошло то, что говорят "всё новое - хорошо забытое старое"
Вспомнил про новую технологию из UE5 под названием Nanite - когда мы берем меш, разбиваем его на кластеры по 64-128 полигонам, и нумеруем их по ID
А дальше просто из камеры, по каждому пикселю, пускаем луч. И если тот попал в полигон - записываем в специальный буфер (VisBuffer) ID Меша, Кластера и Полигона (а затем на втором рендер-пассе раскрашиваем/растеризуем их, но не суть)
К чему все это? Так к тому, что эти последовательные 2 шага.... Чертовски напоминают мне Wolfenstein 3D аж из 1992 года!
Ведь вспомните - тогда математика на процессорах была чертовски дорога. Проходиться циклом по каждой стенке/псевдо-полигону, проецировать его точки, считать матрицы, а потом еще закрашивать - непозволительная роскошь...
И тогда молодой Кармак придумал - а что если просто пускать луч из камеры, находить стену, расстояние до нее, и сразу же красить? Так и родился легендарный метод под названием "Рейкастинг"!
И в чем моя мысль: Если так посудить... Nanite - это идеальное продолжение идеи Кармака, возведенная в абсолют!
Вместо 2д лучей - 3д. А вместо прямого "сделал пересечение - покрасил" у нас сначала запоминание пересечений во временный буфер (VisBuffer), а уже затем - покраска по этому буферу
всё новое - хорошо забытое староe ;P
❤🔥4👀1