All streams
Search
Write a publication
Pull to refresh
77
0
Send message
Отсутствие fpu дает возможность кастовать к float'у, потому что float — 4 байта и читается обычной ldr, которая поддерживает невыровненный доступ. Поэтому я и писал про double :)
А вот double читается командой ldrd, которая поддерживает только выровненный доступ. Правда, я слегка приврал, надо, чтобы было выровнено по 4, не по 8, но не суть.
Пруф.

Вот на Cortex-M4F, где есть fpu, уже и float'ы трогать через кривой указатель нельзя, fpu в невыровненный доступ совсем не умеет.
Ну, не стал бы так категорично утверждать.

А можете пример без нарушения придумать?

И в любом случае кошерное обертывание в std::launder в таких случаях (не выровненный доступ) не спасёт.

Ну, это понятно, да. Видимо, предполагается, что тут программист просто говорит компилятору — «спокуха, я знаю, что делать».
Собственно, единственная причина, по которой можно создать такой указатель — нарушение strict aliasing'a :) Вот в какой точно момент он нарушается — сразу при создании или при первом применении (не важно, на чтение или на запись) — тут судить не берусь, это уже нюансы.
Насколько я понимаю стандарт, UB наступает ровно в момент reinterpret_cast'a. Все, что происходит после неопределено никак.
То, что сейчас компилятор генерирует код, который делает что-то вменяемое — счастливая случайность.

Допустим, если слегка поменять типы, а архитектуру выбрать ARM Cortex-M3, то можно устроить вот такое:
char array[8] = {0};
double * d = reinterpret_cast<double *>(array);
*d = 8.8;
double dd = *d;

Тут с вероятностью 7/8 ошибка будет уже при записи 8.8 по указателю d, потому что на этой архитектуре доступ к double должен быть выровнен по границе 8 байт.

На мой взгляд, ваш код принципиально ничем не отличается и будет работать просто потому, что конкретная архитектура вам это позволяет сделать.
Но если копнуть, вполне может оказаться, что не всегда. Например, могут найтись такие значения int, которые будут соответствовать некорректным значениям для float (что-нибудь в районе двоичного представления NaN, например), что породит исключение. Или типа того.
Это вообще ничего не значит. Если в коде UB, то компилятор может генерировать любой код, в том числе ожидаемый человеком.
Попробуйте оптимизацию повключать, вполне возможно, что результат изменится.

Но даже если нет — это не показатель отсутствия UB.
Эээ, почему-то это вдруг будет код без алиасинга? Сам по себе reinterpret_cast не делает этот код не-UB.
Мне тоже неочевидно, поэтому я и хотел бы видеть это в статье.
В cppreference тоже есть кусок с reinterpret_cast:
  alignas(Y) std::byte s[sizeof(Y)];
  Y* q = new(&s) Y{2};
  const int f = reinterpret_cast<Y*>(&s)->z; // Class member access is undefined behavior:
                                             // reinterpret_cast<Y*>(&s) has value "pointer to s"
                                             // and does not point to a Y object 
  const int g = q->z; // OK
  const int h = std::launder(reinterpret_cast<Y*>(&s))->z; // OK
Этот ответ предлагает reinterpret_cast с нарушением strict aliasing'а как один из примеров применения. Кто не прав?
Не освещен std::launder, который вроде как для отмены алиасинга появился.
Но вообще, я говорил немного не об этом, а о том, что в каждом новом языке заново переизобретают стандартную библиотеку GUI в частности.
Биндинги к Qt встречаются примерно так же часто, как и обертки над сишными вызовами — т.е. часто, но все равно требуют большого количества оберточного бойлерплейта.
Я полагаю, что это зависит от конкретного приложения. Кому хорошо, а кому и не очень.
Да, только окна выглядят по-разному, шрифты выглядят по-разному и т.д. Есть, короче говоря, нюансики.
Теоретически — да. Практически, повторов довольно много — почти вся математика, работа со строками, разбор аргументов командной строки… И GUI раз за разом изобретают заново, да все никак не изобретут так, чтоб кроссплатформенно вышел (Electron'ы, молчать!).
Меня вот больше удивляет, что каждый год появляются новые языки программирования и люди каждый раз заново пишут для них стандартную библиотеку. Все то же самое, что было уже миллион раз написано.
В лучшем случае — пишут обертки для уже существующих библиотек.

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

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

И в результате мой супер-пупер-абстрактный платформонезависимый код начинает обрастать условной компиляцией чтобы учитывать все эти особенности. Какое уж там «сделай табуретку».
Резонно, но максимум в 20 символов, который я достаточно регулярно вижу, это все-таки как-то маловато.
Я, если честно, вообще в упор не понимаю, зачем ограничивать максимальную длину пароля. Он там что, в базе хранится строкой в открытом виде?
Да, виноват, в гугле промахнулся. Смотрел эррату на 1921вк01.
Спасибо! По даташиту выглядят вкусно. Но и эррата тоже богатая.
А смысл-то в этом есть? :) Вы прикиньте сначала, может мотаться в прерывание и обратно будет даже дольше.
Вот если DMA поднять — возможно смысла будет больше.
Как ни странно, ни разу не испытывал потребности в прерываниях от SPI, всегда хватало просто задрать скорость и тупо флаги поллить блокирующе.
Обычно нужно перекинуть два-три байта, вполне можно себе позволить.

Information

Rating
4,832-nd
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity