Piszę aplikację c dla STM32F105, używając gcc.
W przeszłości (z prostszych projektów), zawsze zdefiniowane jako zmienne char
, int
, unsigned int
, i tak dalej.
Widzę, że to jest wspólne korzystanie z typów zdefiniowanych w stdint.h, takie jak int8_t
, uint8_t
, uint32_t
, itd. To prawda, że w wielokrotnością API, które używam, a także w bibliotece ARM CMSIS od ST.
Wierzę, że rozumiem, dlaczego powinniśmy to robić; aby umożliwić kompilatorowi lepszą optymalizację przestrzeni pamięci. Spodziewam się, że mogą istnieć dodatkowe powody.
Jednak ze względu na zasady promocji liczb całkowitych c, ciągle napotykam ostrzeżenia o konwersji za każdym razem, gdy próbuję dodać dwie wartości, wykonać operację bitową itp. Ostrzeżenie brzmi mniej więcej tak conversion to 'uint16_t' from 'int' may alter its value [-Wconversion]
. Zagadnienie to jest omawiane tutaj i tutaj .
Nie dzieje się tak przy użyciu zmiennych zadeklarowanych jako int
lub unsigned int
.
Podając kilka przykładów, biorąc pod uwagę:
uint16_t value16;
uint8_t value8;
Musiałbym to zmienić:
value16 <<= 8;
value8 += 2;
do tego:
value16 = (uint16_t)(value16 << 8);
value8 = (uint8_t)(value8 + 2);
To brzydkie, ale mogę to zrobić w razie potrzeby. Oto moje pytania:
Czy istnieje przypadek, w którym konwersja z niepodpisanego na podpisany i z powrotem na niepodpisany spowoduje niepoprawny wynik?
Czy są jakieś inne ważne powody, dla których warto używać typów całkowitych stdint.h?
W oparciu o odpowiedzi, które otrzymuję, wygląda na to, że typy stdint.h są ogólnie preferowane, nawet jeśli c konwertuje uint
do int
iz powrotem. To prowadzi do większego pytania:
- Mogę zapobiec ostrzeżeniom kompilatora, używając rzutowania czcionek (np
value16 = (uint16_t)(value16 << 8);
.). Czy po prostu ukrywam problem? Czy jest lepszy sposób, aby to zrobić?
value8 += 2u;
i value8 = value8 + 2u;
, ale dostaję te same ostrzeżenia.
8u
i2u
.