Я пишу приложение в c для STM32F105, используя gcc.
В прошлом (с более простыми проектами), я всегда определяются переменные , как char
, int
, unsigned int
и так далее.
Я вижу , что он является общим для использования типы , определенные в stdint.h, такие как int8_t
, uint8_t
, uint32_t
и т.д. Это правда , что в многокорпусных API, который я использую, а также в библиотеке ARM CMSIS от ST.
Я считаю, что понимаю, почему мы должны это делать; чтобы позволить компилятору лучше оптимизировать пространство памяти. Я ожидаю, что могут быть дополнительные причины.
Однако из-за целочисленных правил продвижения в c я продолжаю сталкиваться с предупреждениями преобразования каждый раз, когда пытаюсь добавить два значения, выполнить побитовую операцию и т. Д. Предупреждение выглядит примерно так conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
. Вопрос обсуждается здесь и здесь .
Это не происходит при использовании переменных, объявленных как int
или unsigned int
.
Чтобы дать пару примеров, учитывая это:
uint16_t value16;
uint8_t value8;
Я должен был бы изменить это:
value16 <<= 8;
value8 += 2;
к этому:
value16 = (uint16_t)(value16 << 8);
value8 = (uint8_t)(value8 + 2);
Это некрасиво, но я могу сделать это при необходимости. Вот мои вопросы:
Есть ли случай, когда преобразование из неподписанного в подписанное и обратно в неподписанное приведет к неверному результату?
Существуют ли другие серьезные причины для / против использования целочисленных типов stdint.h?
Судя по полученным ответам, похоже, что типы stdint.h, как правило, предпочтительнее, хотя c преобразует uint
в int
и обратно. Это приводит к большему вопросу:
- Я могу предотвратить предупреждения компилятора, используя приведение типов (например
value16 = (uint16_t)(value16 << 8);
). Я просто скрываю проблему? Есть ли лучший способ сделать это?
value8 += 2u;
и другое value8 = value8 + 2u;
, но получаю одинаковые предупреждения.
8u
и2u
.