TLDR
Выполнение чего-либо вроде передачи адреса uint8_t
чему-то ожидающему адрес uint32_t
может привести к повреждению памяти, неизвестным результатам, незначительным ошибкам и просто код взрывается.
ДЕТАЛИ
Сначала, если функция объявлена как
void func( uint32_t * arg );
и изменяет данные arg
указывает на то, что передача ему адреса uint8_t
или uint16_t
приведет к неопределенному поведению и вероятности повреждения данных - если он вообще будет работать (продолжайте читать ...). Функция будет изменять данные, которые на самом деле не являются частью объекта, на который ссылается указатель, переданный в функцию.
Функция, как ожидается, будет иметь доступ к четырем байтам uint32_t
, но вы дали ей адрес только один uint8_t
байтов. Где остальные три байта go? Скорее всего, они нападают на что-то другое.
И даже если функция только читает память и не изменяет ее, вы не знаете, что находится в памяти, а не в реальном объекте, поэтому функция может вести себя непредсказуемо , И чтение может вообще не работать (продолжайте читать снова ...).
Кроме того, приведение адреса uint8_t
является строгим нарушением псевдонимов. См. Что такое строгое правило псевдонимов? . Подводя итог, можно сказать, что в C вы не можете безопасно ссылаться на объект как на то, чем он не является, за исключением того, что вы можете ссылаться на любой объект, как если бы он состоял из правильного числа [signed|unsigned] char
байтов.
Но приведение uint8_t
адреса к uint32 *
означает, что вы пытаетесь получить доступ к набору из четырех unsigned char
значений (предполагая, что uint8_t
на самом деле unsigned char
, что почти наверняка верно в настоящее время) как один uint32_t
объект, и это строгое нарушение псевдонимов, неопределенное поведение и небезопасное.
Симптомы, которые вы видите при нарушении правила строгого псевдонима, могут быть тонкими и действительно трудно найти и исправить. См. g cc, строгие псевдонимы и ужасные истории для некоторых, ну, ужасных историй.
Кроме того, если вы ссылаетесь на объект как на нечто нет, вы можете столкнуться с 6.3.2.3 указателями , параграф 7 стандарта C (C11) :
Указатель на объект Тип может быть преобразован в указатель на другой тип объекта. Если результирующий указатель неправильно выровнен для ссылочного типа, поведение не определено.
Это небезопасно даже на x86, независимо от того, что кто-то может рассказать вам о системах на базе x86.
Если вы когда-нибудь услышите, как кто-то скажет: «Ну, это работает, так что все не так.», Ну, они очень, очень неправы.
Они просто не наблюдали этого не удается.
пока.