До сих пор я в основном слышал, что вы должны как можно больше использовать типы без знака (особенно?) На встроенных устройствах
Это верно главным образом по той причине, что (случайно или намеренно) операнды со знаком, смешанные с побитовыми операторами, создают havo c. Но в низкоуровневом программировании не так много случаев, когда вам действительно нужно использовать подписанные типы.
Например, MISRA- C заставляет вас всегда использовать беззнаковые переменные, операнды и целочисленную константу если только не является намерением использовать подписанный тип. Так что это не просто что-то основанное на мнениях, MISRA- C является де-факто отраслевым стандартом для большинства профессиональных встраиваемых систем.
, поэтому я начал использовать массивы uint8_t для хранения строк
Это нормально, но не неправильно использовать char
для этой цели. только время, когда можно использовать char
, - это когда вы собираетесь хранить текст. Обратите внимание, что char
особенно неприятен, потому что в отличие от всех других типов в языке, он имеет неизвестную подпись. Каждый компилятор может сделать char
подписанным или неподписанным и при этом соответствовать стандарту C. Поэтому код, полагающийся на то, что char
подписан или не подписан, не работает. Однако для текстовых строк это не имеет значения, поскольку они всегда положительны.
Однако, если я вызываю itoa из stdlib.h, он ожидает указатель на массив char (int8_t) со знаком:
Ваш компилятор обрабатывает char
как подписанное тогда. Прежде всего, обратите внимание, что itoa
не является стандартным C и не может существовать внутри stdlib.h
, когда требуется строгое соответствие C стандарту. Но что еще более важно, разные компиляторы могут реализовывать функцию по-разному, поскольку она не стандартизирована.
Как оказалось, вы можете безопасно выполнять дикое приведение между различными типами символов: char
, unsigned char
, signed char
, int8_t
и uint8_t
(8-битные типы stdint.h почти наверняка являются символьными типами, даже если стандарт не говорит об этом явно). С типами символов, в частности, связаны различные специальные правила, означающие, что вы всегда можете привести что-либо к типу символа.
Вы можете безопасно преобразовать свой массив uint8_t
в char*
, если есть квалификаторы отсутствуют (const
et c).