Перейти к содержанию
    

Лидеры

Популярный контент

Показан контент с высокой репутацией 22.10.2023 во всех областях

  1. Именно за счет расширений и можно писать понятный код и писать его проще, ежели как это позволял бы голый стандарт. Да, в общем случае UB может привести к любым результатам - как правильным, так и неправильным. Но практически все современные компиляторы имеют расширения. Всякие __unaligned, __packed, и т.д. - все эти ключевые слова отсутствуют в стандарте, но их четко описывают в документации на компилятор. Тогда с чего компилятор будет генерировать UB? В прошлый раз (в теме, которую Вы указали) мы обсуждали не UB по выравниванию, а UB из-за доступа к volatile между двумя точками следования. У компилятора на этот счет нет описания в справочнике, а значит имеет смысл делать предположения о следовании его стандарту. Вот и все. Касательно расширений продолжу. u32 *p = 'address'; Компилятору никаких специальных указаний нет, поэтому он предполагает, что 'p' содержит валидный выровненный указатель. При доступе будет сгенерирована команда чтения/записи 32-битного слова (или кучка команд доступа по частям) - имеет право. Если указатель не выровнен, то поведение не определено: если компилятор уже знает о том, что адрес не выровнен, то ассемблерный листинг может весьма удивить. В противном случае лишь юзер может знать, во что выльется (возможное) применение невыровненного доступа на его процессоре. __unaligned u32 *p = 'address'; Компилятор заранее наделили знанием, что указатель может содержать невыровненный адрес. Тут UB с точки зрения выравнивания нет. Компилятор сгенерирует любую из удобных (поддерживаемых CPU) инструкций доступа по адресу в 'p'. u32 volatile *p = 'address'; Компилятор предполагает, что 'p' содержит выровненный указатель. В отличие от первого случая, процессор не может читать/писать значение по указателю "частями", потому что это нарушит семантику обращений/изменений volatile-объекта между двумя точками следования. Поэтому компилятор строго предполагает, что адрес тут точно выровнен, и никак иначе. Он однозначно генерирует инструкцию 32-битного доступа. Если же в этот указатель каким-то образом поместился невыровненный указатель (динамически, в run-time), то, как и в первом случае, лишь юзеру будет ясно, чем это чревато. Если же компилятор на этапе компиляции уже будет видеть неровный указатель - UB, может такой доступ запросто вовсе выкинуть из кода, прихватив все зависимое. __unaligned u32 volatile *p = 'address'; Итак, у 'p' два атрибута: __unaligned и квалификатор volatile у объекта, на который он показывает. Их бы надо как-то поженить между собой. Однако это невозможно, т.к. невыровненный доступ по указателю, помеченному __unaligned, вроде, и определен, но volatile накладывает свое "вето" на эту невыровненность, потому что иначе сломается семантика доступа к volatile. Т.е. компилятор должен тут решить, как ему поступать в данном случае: 1) "закрыть глаза" на строгую семантику доступа к volatile в части кол-ва обращений к объекту (при этом не оптимизировать сам доступ), разрешая таким образом работу с невыровненным указателем; 2) пытаться соблюсти корректный доступ к volatile-объекту, а это ничто иное как обеспечить однократный доступ к памяти инструкцией соответствующей разрядности доступа - а для этого нужно отбросить __unaligned и "задним числом" положиться на программиста, что указатель гарантированно выровнен. Если же юзер указатель не выровнил, то вылезет UB по отношению к volatile-объекту (ведь по отношению к обычному доступу UB уже "заранее" парирован ключевым словом __unaligned). Судя по листингам, по первому пути пошел GCC, а по второму LLVM/CLang, который мне, в свою очередь, и кажется более правильным. Вот если есть __unaligned или что-то подобное в компиляторе, то проблем нет. Напрямую "натягивать" указатель типа структуры на память может выйти боком при strict aliasing, но эта проблема решаема: в C++, например, с помощью placement new.
    1 балл
  2. Я ж говорю - пока нет видео или хотябы полного описания дефекта дергания, тут нельзя однозначно сказать. Вероятно, за целый год работы там накопилось уже столько мелких косяков, что сбоит от каждого чиха. Кстати, судя по соседней теме того же автора, у него вообще какие-то фееричные проблемы с проектом - после перепрошивки МК не может подключиться к нему отладчиком.
    1 балл
×
×
  • Создать...