printf com sizeof em 32 vs 64 plataformas: como faço para lidar com código de formato de forma independente de plataforma?

StackOverflow https://stackoverflow.com/questions/1403074

  •  05-07-2019
  •  | 
  •  

Pergunta

Eu tenho algum código que imprime a quantidade de memória utilizada pelo programa. A linha é semelhante a este:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

onde anIntVariable é uma variável int para o número de elementos da matriz dupla. De qualquer forma, em sistemas de 32 bits Eu nunca tive quaisquer problemas, mas em sistemas de 64 bits, eu recebo um aviso do compilador sobre o uso de "% u" para um inteiro longo não assinado. Usando "% lu", como as correções de código formato o problema em 64-bit, mas faz com que o compilador para reclamar em 32-bit porque o tipo está de volta ao int não assinado. Eu descobri que, na verdade, sizeof (double) retorna um valor diferente em 32 vs 64 bit sistemas. Eu encontrei alguns guias página da Web para converso código de 32 bits para 64 bits, mas eu prefiro ter um código que funciona tanto em vez de apenas converter e para trás.

Como faço para escrever esta linha de uma forma independente de plataforma? Eu sei que muitas maneiras que eu poderia fazer isso usando diretivas de pré-processamento, mas que parece ser um hack. Certamente há uma maneira elegante que eu não estou percebendo.

Foi útil?

Solução

identificadores printf portáteis são fornecidos no arquivo de inclusão inttypes.h .

Este arquivo de inclusão tem muitos identificadores portáteis para o seu tempo de execução específico. Para o seu exemplo, você quer PRIuPTR, que significa " PR intf I dentifier u nsigned com tamanho de até o tamanho de um ponteiro".

Seu exemplo será então:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

Os resultados em 64bit Linux com GCC 4.3 (int anIntVariable = 1):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

Para sermos mais completos, existem identificadores para scanf também, cujos prefixos são SCN.

Outras dicas

O valor de retorno de sizeof é um size_t. Se você estiver usando um compilador compatível C99 parece que você pode usar %zd %zu para isso.

D'oh: %zu (não assinado) é claro. Obrigado, ony.

Em primeiro lugar, você deve coincidir com o especificador "%" com o tipo de dados real que você deseja imprimir. sizeof retorna o tipo de dados size_t , e assim como você não deve tentar imprimir um flutuador usando um "% d" especificador, você não deve tentar imprimir um size_t com "% u" ou "% d" ou qualquer coisa que não size_t realmente significam.

As outras respostas deram algumas boas maneiras de lidar com isso com compiladores mais recentes ( "% z" e PRIu32), mas a maneira que usamos para fazer isso era simplesmente para lançar o size_t para unsigned long, e, em seguida, imprimi-lo usando " % lu ":

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

Isso não vai funcionar em sistemas onde size_t é mais largo do que um tempo, mas eu não sei de qualquer um desses sistemas, e eu nem tenho certeza se o padrão permite.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top