Mam następujące
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
Podczas kompilacji pojawia się następujące ostrzeżenie:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
Kiedy przeprowadziłem to za pomocą szyny, otrzymałem:
Format argument 1 to printf (%u) expects unsigned int gets size_t: k
Wielkie dzięki za wszelkie rady,
uint32_t
z<stdint.h>
lub<inttypes.h>
; jeśli chcesz używać tych typów, powinieneś uaktualnić do C89. Jako rozszerzenie jest prawdopodobne, że GCC pozwala na ich użycie, ale C89 nie miał takiej obsługi.size_t
jest „z”, jak w"%zu"
.uint32_t
, ale jej brakujesize_t
. Odpowiedź @ u0b34a0f6ae obejmuje oba.Odpowiedzi:
Wygląda na to, że spodziewasz
size_t
się tego samegounsigned long
(prawdopodobnie 64 bity), gdy w rzeczywistości jest tounsigned int
(32 bity). Spróbuj użyć%zu
w obu przypadkach.Nie jestem jednak do końca pewien.
źródło
int32_t
tak się składa, że znajduje sięint
na twoim kompilatorze / platformie, nie oznacza, że może nie byćlong
na innym. To samo dotyczysize_t
. W rzeczywistości wychodzi z drogi i wykonuje więcej pracy, aby wykryć ten błąd przenośności, ponieważ prostym, naturalnym sprawdzeniem byłoby po prostu honorowanie typedef, tak jak robi to kompilator.%lu
razem z(unsigned long)k
jest zawsze poprawne.size_t
jest trudniejszy, dlatego%zu
został dodany w C99. Jeśli nie możesz tego użyć, potraktuj to tak samok
(long
jest największym typem w C89,size_t
jest mało prawdopodobne, aby był większy).Próbować
Symbol
z
reprezentuje liczbę całkowitą o takiej samej długości jaksize_t
, aPRIu32
makro zdefiniowane w nagłówku C99inttypes.h
reprezentuje 32-bitową liczbę całkowitą bez znaku.źródło
printf( "%lu", (unsigned long )i )
. W przeciwnym razie kończy się później stosem ostrzeżeń w całym kodzie z powodu zmiany typu.uint32_t
więc w rzeczywistości jest to kod C99 i powinien być skompilowany jako taki.Potrzebne jest tylko to, aby specyfikatory formatu i typy były zgodne i zawsze możesz rzutować, aby to było prawdą.
long
ma co najmniej 32 bity, więc%lu
razem z(unsigned long)k
jest zawsze poprawne:size_t
jest trudniejszy, dlatego%zu
został dodany w C99. Jeśli nie możesz tego użyć, potraktuj to tak samok
(long
jest największym typem w C89,size_t
jest mało prawdopodobne, aby był większy).Jeśli specyfikatory formatu nie są prawidłowe dla typu, który przekazujesz,
printf
spowoduje to odczytanie zbyt dużej lub zbyt małej ilości pamięci z tablicy. Tak długo, jak używasz wyraźnych rzutów, aby dopasować typy, jest przenośny.źródło
Jeśli nie chcesz używać makr PRI *, innym podejściem do drukowania DOWOLNEGO typu liczby całkowitej jest rzutowanie na
intmax_t
lubuintmax_t
i użycie odpowiednio"%jd"
lub%ju
. Jest to szczególnie przydatne na przykład w przypadku typów POSIX (lub innych systemów operacyjnych), które nie mają zdefiniowanych makr PRI *off_t
.źródło