Pull to refresh
-10
Karma
0.3
Rating
Александр @panteleymonov

Программист

Кривые в компьютерной графике. Урок 1: Анимации

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

Все бы ничего, но есть два дополнения:

квадратичная кривая Безье = lerp(lerp(p0,p1,t),lerp(p1,p2,t),t)

кубическая кривая Безье = lerp(lerp(lerp(p0,p1,t),lerp(p1,p2,t),t),lerp(lerp(p1,p2,t),lerp(p2,p3,t),t),t)

https://www.desmos.com/calculator/hfqqnck5g4?lang=ru

Ну и остальное = lerp(p0,p1,F(t))

Защитники думают списками, атакующие думают графами. Пока это так, атакующие будут побеждать

Защитники думают списками, атакующие думают графами.

Не будем забывать, что граф можно описать как списки вершин и соединений между ними.

Библиотека вывода с использованием escape-последовательностей

М-да, теперь тетрис в килобайты не написать - буст нужен!

Feature freeze С++23. Итоги летней встречи комитета

Опять вы путаете теплое с мягким и вводите в заблуждение других. Вопрос был про "Выделить массив байт" и "А вот когда указатель p был сформирован внутри компилируемой программы", где по вашему якобы помогает start_lifetime_as. И любому знающему человеку должно быть понятно в чем разница между разными парами "выделить"/"удалить" память, поскольку это разные менеджеры/системы памяти. Что собственно и делает start_lifetime_as, отключая у неявного объекта деструктор и конструктор. Поэтому ни какое ваше "кастануть его в указатель на структуру и обратиться к полю - UB" неверно ни для одного стандарта, до тех пор пока вы явно или неявно не вызвали деструктор или конструктор и не начали оперировать с таким объектом стандартными методами.

Feature freeze С++23. Итоги летней встречи комитета

А вот и нет. Выделить массив байт, кастануть его в указатель на структуру и обратиться к полю — это UB в плюсах независимо ни от каких выравниваний и прочего.

Во первых, а вои и да:

Since C++20, certain functions in the C++ standard library such as malloc, bit_cast, and memcpy are defined to implicitly create objects [P0593R6]. As a result, the following code is no longer undefined behaviour:

struct X { int a, b; };
X* make_x() {
  X* p = (X*)malloc(sizeof(struct X)); // implicitly creates an object of type X
  p->a = 1;
  p->b = 2;
  return p;
}

Хотя опять же это все определенные условия, при которых это можно было делать и раньше. Но

Во вторых, это утверждение по прежнему равнозначно для обоих примеров.

С чего бы тут была проблема из-за временного буфера?

Немного ошибся с переводом, но тем не менее читайте описание start_lifetime_as и того что оно на самом деле делает, а не то что вы предполагаете (ссылка у меня выше и в статье). Это то, из-за чего нельзя сначала сделать malloc, а потом delete. (чего нормальному человеку в голову не придет) Собственно это и есть те условия, обходя которые можно уйти от UB.

Feature freeze С++23. Итоги летней встречи комитета

А вот когда указатель p был сформирован внутри компилируемой программы — тут-то UB и вылезает на свет, угрожая покорёжить программу на этапе оптимизации.

Вы понимаете что здесь точно также можно сказать что "Разумеется, если фактическое расположение и выравнивание полей соответствует ожидаемому — то reinterpret_cast работает без всякого UB." ? Кроме того также выделение памяти под объект выполнено соответствующими средствами С++. В результате эти примеры равнозначны.

И именно здесь start_lifetime_as очень даже спасает.

По вашему описанию выглядит как static_cast.

А из примера:

void process(Stream* stream) {
   std::unique_ptr buffer = stream->read();
   if (buffer[0] == FOO) processFoo(reinterpret_cast(buffer.get())); // undefined behaviour
   else processBar(reinterpret_cast(buffer.get())); // undefined behaviour
} 

Видно что проблема здесь опять не в reinterpret_cast, а в том что buffer временный. Что из примера в статье выше это ни как не видно. И тут тоже можно обойтись исправлением без start_lifetime_as, копирования и UB.

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2590r2.pdf

Feature freeze С++23. Итоги летней встречи комитета

std::start_lifetime_as

Почему-то ощущение что это какой-то костыль.
На счет того, что какой-нибудь:

void fun(const char* p) {
	const SomeStruct* str = reinterpret_cast<const SomeStruct*>(p)
  ...

Считается UB, мнения постоянно делятся и из-за этого родилось, то что родилось.
Все неопределенное поведение тут завязано только на отправителе или источнике указателя p, и к текущему коду никакого отношения не имеет. Как например, если этот указатель был получен из другого языка или компилятора где char 2 байта или имеет специфическое выравнивание. То есть вся проблема из-за расплывчатого описания стандарта. В этом смысле start_lifetime_as тоже мало чем поможет. А сама пометка неопределенного поведения подразумевает что угодно. Конкретно здесь несоответственное расположение данных полям структуры SomeStruct и тому что объект, который будет использоваться как SomeStruct, на самом деле им не был.

То есть можно сделать вывод, что start_lifetime_as просто затычка, чтобы люди закончили по этому поводу спорить. Но это же ни чего не меняет. По сути тот же const SomeStruct* str = (const SomeStruct*)p. из С, который по своей природе в этом плане тоже не определен.

void ReceiveData(std::span<std::byte> data_from_net) {

Из примера видно что данные получены не внутри компилированной программы. Соответственно start_lifetime_as никак не помогает. Тем более это набор байт, а не другая структура, что в принципе не дает для start_lifetime_as ни какой информации о исходном типе.

Миф о незаменимом разработчике

А почему не со второго? Или вы думаете, что человек с кратковременным инсультом или скачущим давлением, имея за своими плечами годы опыта не превратиться в одночасье в ничего не понимающего человека?

И потом что вы подразумеваете под своим понятием "любой код"? Он что должен на слух данные с модема читать? С вашими якобы правильными выводами попахивает троллингом.

Как я уже сказал в рамках фирм в которых я работал это вполне рабочее высказывание, мало того является одним и перефразированных мною правил. Не надо забывать что они не работают без гита и документированных постановок задач, где вполне себе доступным языком описывается все внесенные в код правки начиная с 90-x. Но даже с этим приходиться рефакторить код годами.

А вы приводите примеры из фирм, которые обычно на моих глазах закрывались после ухода этого самого "незаменимого".

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

Приведу в пример работу одного из отделов Касперского, где код анализируют по бинарникам и в поставленные сроки нужно проанализировать работу опкода для написания отчета, чтобы судья или следователь смог вынести приговор или задержать злоумышленника. И тут очевидно отмаза "нет документации" не прокатит, и растянуть сроки не получиться, поскольку по дедлайну человека просто отпустят за неимением доказательств из-за вашей некомпетентности. А завтра отпущенный позвонит вам и расскажет что вы ему должны за его нервы. Или за то что выполнили задачу будете потом еще угрозы получать.

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

Миф о незаменимом разработчике

А вам станет легче, если в коде будет комментарий на подобии:
"Начальник был самодур или пьян и решил проверить сможем ли мы добавить такое правило, и я его добавил, удачи!"

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

А если он вам в тумбочку нагадил... и тд и тп. Причем тут комментарии и документация?

Незаменимых конечно же нет, но нужно не забывать про теорию вероятности и сводить все риски к минимуму. И комментарии тут только предлог и критерий, а никак не рычаг устранение проблемы, потому что код иногда из бинарников восстанавливать приходиться. И приветы передавать не только соседу по кабинету, но и разработчикам OS и фреймворков, чтоб они пофиксили свои костыли, включая недописанные драйвера от закрытых операционных систем оригинальных устройств.

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

Миф о незаменимом разработчике

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

Нужно комментировать участки кода, по которому могут возникнуть вопросы.

Код по которому возникают вопросы и прочая магия - это всегда код вне компетенции читающего.

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

Миф о незаменимом разработчике

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

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

Миф о незаменимом разработчике

В наше время разработчики меняют компании как перчатки.

Поэтому компании должны быть готовы к тому, что любой разработчик может уйти в любой момент. Жужжание в уши и повышение зарплаты на 3% больше не работают. Хотя не факт, что они работали и раньше.

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

Не писать документацию.

Писать дрянной код

Единолично владеть некой основной частью системы

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

Double, Float — не вещественные числа

И так я не увидел достаточного теоритического обоснования почему моя позиция не верна ...

Напоминаю позицию: "Double и Float не вещественные числа т.к. ни одно иррациональное число не входит в область покрываемых значений".

Ищем 10 отличий.

Double, Float — не вещественные числа

Это выдуманый критерий из их головы, я такого не говорил.

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

Double, Float — не вещественные числа

"Вещественные числа dooble float" - это взгляд математика на программирование. Возникает такая же проблема когда теоретики С++ (или другого высокоуровневого языка или теории) начинают рассуждать о работе процессора (или чем-то вещественном и реальном).

И все таки числа с плавающей точкой - это один из вариантов представления вещественного числа для вычислительной машины. А то что можно записать только часть рациональных, ну так получилось. Даже не все рациональные здесь имеются, то есть dooble рациональным тоже назвать нельзя. С точки зрения расчетов до нескольких знаков после запятой, число 1/3 0.3333333432674407958984375 можно считать как бесконечную дробь, в том числе и урезанную ПИ как полную запись.

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

(пака писал уже подобные мысли выше появились)

В Data Science не нужна математика (Почти)

Мне почему-то все это напомнило моделирование на shadertoy.

Опять про простые числа

Там их больше, в последнем столбце 4 простых и 4 не простых.

Раздувание кода стало астрономическим

То что, к примеру, я пишу на С для одной ОС и потом переписываю для другой не делает конечную библиотеку больше.

Если взять тот же Qt с требованиями "разработать с использованием QML", прицепить базу данных и использовать сервисы ОС (погода, положение, и тд) - это будет гиговый дистрибутив в отдельном каталоге не считая библиотек операционной системы. Но при статической линковке это всего лишь 12 мегабайт. А если взять весь функционал напрямую из ОС то приложение будет не больше метра.

Не будем также забывать про существование KolibriOS.

Holy C++

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

Вот вам другое мнение для размышления: почему язык C++ развивается не согласованно со стандартами языка С? Как это подразумевалось при его создании чтобы расширить возможности С. А рождает вместо этого противоречивые костыли.

Этот язык программирования появился в начале 80-х годов ХХ столетия. Придумал его Бьерн Страуструп. Создавался С++ на базе существовавшего тогда С. Первоначально, Страуструп назвал новый язык «С с классами», так как в нем были реализованы классы. Помимо этого, в новый язык программирования были добавлены виртуальные функции, ссылки, константы и многое другое. Также здесь появился новый стиль комментирования (привычные многим //). В результате получившийся язык программирования перестал быть дополнением в С и стал самостоятельным.

Математика для 3D-приложений. Урок 1

vec3 new_dir = dir - normal * dir(dir, normal);

Во первых функция не dir, а dot. Во вторых умножение на два забыли, иначе получится вектор параллельный плоскости отражения (не совсем понятно что имелось в виду).

https://docs.gl/sl4/reflect

vec3 new_dir = dir - 2 * dot(dir, normal) * normal;

Если хотели сделать направление по плоскости то нужно не забыть нормализовать его, или восстановить скорость/длину вектора.

Information

Rating
1,658-th
Location
Королев, Москва и Московская обл., Россия
Date of birth
Registered
Activity