W C ++ liczby całkowite o stałej szerokości są zdefiniowane jako opcjonalne , ale nie mogę znaleźć zalecanego sposobu sprawdzenia, czy są one faktycznie zdefiniowane.
Jaki byłby przenośny sposób sprawdzenia, czy dostępne są liczby całkowite o stałej szerokości?
#if defined(INT8_MIN)
cpp
pliku i zależnie od tego, czy kompilacja się nie powiedzie, czy nie, można ustawić makro, które można zdefiniować.AC_TYPE_INT8_T
itp.Odpowiedzi:
Aby ustalić, czy rodzaj całkowitą stałej szerokości jest, można sprawdzić, czy którykolwiek z odpowiadającymi
[U]INT*_MAX
lub[U]INT*_MIN
makr jest zdefiniowana.Według 7.20 typów całkowitych
<stdint.h>
, ust. 4 normy C11 (zwróć uwagę na części pogrubione):C ++ C dziedziczy realizację pośrednictwem
<cstdint>
. Zobacz<cstdint>
vs,<stdint.h>
aby uzyskać szczegółowe informacje. Zobacz także Co oznaczają__STDC_LIMIT_MACROS
i co__STDC_CONSTANT_MACROS
oznaczają? po szczegóły__STDC_LIMIT_MACROS
.Zatem jeśli
int32_t
jest dostępnyINT32_MAX
iINT32_MIN
musi być#define
„d. I odwrotnie, jeśliint32_t
nie jest dostępne, aniINT32_MAX
nieINT32_MIN
mogą być#define
„d.Należy jednak pamiętać, jak stwierdzono w innej odpowiedzi @NicolBolas , może nie być konieczne sprawdzenie.
źródło
[U]INT*_C
zamiast makr min i maxINT64_C
jest zdefiniowany, jeśliint64_least_t
jest dostępny, a nie jeśliint64_t
jest dostępny. Zobacz dokumentacjęMówiąc ogólnie ... nie.
Jeśli musisz użyć liczb całkowitych o stałej wielkości, oznacza to, że wyraźnie potrzebujesz, aby te typy miały określone rozmiary. Oznacza to, że kod nie będzie działał, jeśli nie będzie można uzyskać liczb całkowitych o tych rozmiarach. Więc powinieneś ich po prostu użyć; jeśli ktoś użyje twojego kodu na kompilatorze, który nie ma wymienionych typów, twój kod się nie skompiluje. Co jest w porządku, ponieważ Twój kod nie działałby, gdyby się skompilował.
Jeśli tak naprawdę nie potrzebujesz liczb całkowitych o stałej wielkości, ale po prostu chcesz ich z jakiegoś innego powodu, użyj tych
int_least_*
typów. Jeśli implementacja może dać dokładnie ten rozmiar,least_*
typy będą miały ten rozmiar.źródło
uint8_t
), ale ten kod jakoś musiał działać na platformie, na której bajt nie ma 8 bitów (który oprócz używania stara implementacja C ++, czy byłby to jedyny powód, dlauint8_t
którego nie byłby dostępny)? To znaczy, poza kompatybilnością wsteczną, dlaczego musiałeś to zrobić?uint8_t
było znacznie jaśniejsze niż wcześniejsze podejście ad hoc (i często łamane).O(1)
kontraO(n)
wysiłek. Ten sam powód, dla którego ludzie używają npuint16_t
. Pytasz „dlaczego nie użyć uint32_t i sam go rzucić?”, Na co odpowiedź powinna być oczywista.uint16_t
. Moim powodem jest to, że komunikuję się z urządzeniem / formatem itp., Które spodziewa się uzyskać dokładnie 16 bitów danych sformatowanych jako binarna liczba całkowita bez znaku za pomocą endianu dla mojego komputera i jeśli nie mogę uzyskać typu, który jest właśnie dlatego skuteczna komunikacja z nim jest znacznie trudniejsza. Mój program (i interfejsy API, których z nim używam) zasadniczo nie może działać na komputerze, który tego nie zapewnia.