%X
строго соответствует размеру unsigned int
, поэтому на любой машине, где sizeof unsigned int != sizeof uint8_t*
(например, на большинстве 64-битных машин), он не будет печатать полное значение указателя. Код формата %p
будет печатать указатели с правильно указанным размером указателя, поэтому используйте его для печати адресов памяти.
Чтобы было ясно, как отмечено в комментариях ниже, это фактически неопределенное поведение, даже когда sizeof unsigned int == sizeof uint8_t*
; Я знаю, что указатели хранятся целочисленными способами на всех современных аппаратных средствах, но какая-то будущая система может нарушить эту эквивалентность, и соблюдение стандарта языка - единственный способ гарантировать переносимость. Точно так же, чтобы быть полностью совместимым, вы должны привести указатель к void*
, чтобы напечатать , поскольку %p
специально работает с void*
, а не с «указателями в целом»; в странных системах (например, в системах с сегментированной памятью с концепцией ближних и дальних указателей или в отдельных пространствах памяти для разных типов указателей) uint8_t*
и void*
могут быть не эквивалентны тому, как они хранятся или представляются, но приводятся к void*
всегда должен работать.