Eu tenho o seguinte
size_t i = 0;
uint32_t k = 0;
printf("i [ %lu ] k [ %u ]\n", i, k);
Recebo o seguinte aviso ao compilar:
format ‘%lu’ expects type ‘long unsigned int’, but argument has type ‘uint32_t’
Quando fiz isso usando uma tala, obtive o seguinte:
Format argument 1 to printf (%u) expects unsigned int gets size_t: k
Muito obrigado por qualquer conselho,
uint32_t
de<stdint.h>
ou<inttypes.h>
; se você quiser usar esses tipos, deve atualizar para o C89. Como uma extensão, é provável que o GCC permita que você os use, mas o C89 não tinha esse suporte.size_t
é 'z', como em"%zu"
.uint32_t
, mas não existesize_t
. A resposta de @ u0b34a0f6ae inclui ambos.Respostas:
Parece que você espera
size_t
ser o mesmo queunsigned long
(possivelmente 64 bits), quando na verdade éunsigned int
(32 bits). Tente usar%zu
em ambos os casos.Não estou totalmente certo, porém.
fonte
int32_t
estáint
no seu compilador / plataforma, não significa que pode não estarlong
em outro. O mesmo parasize_t
. Ele está realmente saindo de seu caminho e fazendo mais trabalho para detectar esse bug de portabilidade, já que a verificação fácil e natural seria apenas honrar o typedef como o compilador faz.%lu
junto com(unsigned long)k
está sempre correto.size_t
é mais complicado, por isso%zu
foi adicionado no C99. Se você não pode usar isso, trate-o exatamente comok
(long
é o maior tipo no C89,size_t
é muito improvável que seja maior).Experimentar
O
z
representa um inteiro de comprimento igual asize_t
, e aPRIu32
macro, definida no cabeçalho C99inttypes.h
, representa um inteiro não assinado de 32 bits.fonte
printf( "%lu", (unsigned long )i )
. Caso contrário, acabamos mais tarde com uma pilha de avisos em todo o código devido a uma mudança de tipo.uint32_t
então na verdade é o código C99 e deve ser compilado como tal.Tudo o que é necessário é que os especificadores de formato e os tipos concordem, e você sempre pode lançar para tornar isso verdadeiro.
long
tem pelo menos 32 bits, então%lu
junto com(unsigned long)k
está sempre correto:size_t
é mais complicado, por isso%zu
foi adicionado no C99. Se você não pode usar isso, trate-o exatamente comok
(long
é o maior tipo no C89,size_t
é muito improvável que seja maior).Se você não obtiver os especificadores de formato corretos para o tipo que está passando,
printf
fará o equivalente a ler muita ou pouca memória do array. Contanto que você use casts explícitos para combinar tipos, é portátil.fonte
Se você não quiser usar as macros PRI *, outra abordagem para imprimir QUALQUER tipo inteiro é lançar em
intmax_t
ouuintmax_t
e usar"%jd"
ou%ju
, respectivamente. Isso é especialmente útil para tipos de POSIX (ou outros sistemas operacionais) que não têm macros PRI * definidas, por exemplooff_t
.fonte