Как функция C printf знает, что передан целочисленный размер? - PullRequest
0 голосов
/ 30 мая 2018

В следующем примере кода, откуда printf узнала размер, который должен быть напечатан для uint8_t, в то время как упомянутый формат - только "0x% x", а тип passd - uint32_t?откуда printf узнал, что при первом вызове он должен печатать 4 байта, а при втором вызове он должен печатать только 1 байт?

uint32_t X = 0xAABBCCDD;
printf("uint32_t 0x%x\n", (uint32_t) X);
printf("uint8_t  0x%x\n", (uint8_t) X);

Вывод

uint32_t 0xaabbccdd
uint8_t  0xdd

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

In

printf("uint8_t  0x%x\n", (uint8_t) X);

uint8_t определенно является более ранним типом, чем int, и поэтому uint8_t будет повышен до int и "%x" будет работать.

//potentially invokes UB depending on platform
printf("uint32_t  0x%x\n", (uint32_t) X); 

- это непереносимый код.Теоретически вы не знаете, что такое реальный тип uint32_t, поэтому вам следует использовать макрос PRIx32 из inttypes.h.Для согласованности / простоты вы можете использовать PRIx8 и uint8_t.

#include <inttypes.h>
#include <stdio.h>
int main()
{
    uint32_t X = 0xAABBCCDD;
    printf("uint8_t  0x%" PRIx8 "\n", (uint8_t) X);
    printf("uint32_t 0x%" PRIx32 "\n", (uint32_t) X);
}
0 голосов
/ 30 мая 2018

Не знает.В обоих случаях вы даете printf и [unsigned] int, из-за продвижения аргумента по умолчанию .Ваш код эквивалентен этому: 1

printf("uint32_t 0x%x\n", (unsigned int)(uint32_t) X);
printf("uint8_t  0x%x\n", (int)(uint8_t) X);

Правило продвижения:

[6.3.1.1] Еслиint может представлять все значения исходного типа [...], значение преобразуется в int;в противном случае он преобразуется в unsigned int.

. Единственное правило, которому следует printf на этом этапе, - не печатать начальные нули.

Обратите внимание, что отображение подписанного int до %x - технически неопределенное поведение.


1.Я предполагаю, что у вас есть 32-битные int с.
...