Printf with sizeof en plataformas 32 vs 64: ¿cómo manejo el código de formato de manera independiente de la plataforma?

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

  •  05-07-2019
  •  | 
  •  

Pregunta

Tengo un código que imprime la cantidad de memoria utilizada por el programa. La línea es similar a esta:

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

donde anIntVariable es una variable int para el número de elementos de la doble matriz. De todos modos, en sistemas de 32 bits nunca tuve ningún problema, pero en sistemas de 64 bits, recibo una advertencia del compilador sobre el uso de "% u " para un entero largo sin signo. Utilizando "% lu " como el código de formato soluciona el problema en 64 bits, pero hace que el compilador se queje en 32 bits porque el tipo está de nuevo en int sin signo. Descubrí que, de hecho, sizeof (doble) devuelve un valor diferente en sistemas de 32 vs 64 bits. He encontrado algunas guías de páginas web para convertir código de 32 bits a 64 bits. Pero prefiero tener un código que funcione tanto en lugar de simplemente convertir de un lado a otro.

¿Cómo escribo esta línea de una manera independiente de la plataforma? Conozco muchas formas de hacerlo utilizando directivas de preprocesador, pero eso parece un truco. Seguramente hay una forma elegante de la que no me estoy dando cuenta.

¿Fue útil?

Solución

Los identificadores de impresión portátiles se proporcionan en el archivo de inclusión inttypes.h .

Este archivo de inclusión tiene muchos identificadores portátiles para su tiempo de ejecución específico. Para su ejemplo, desea que PRIuPTR, que significa "dentista PR intf I u esté firmado con un tamaño de hasta el tamaño del puntero ".

Tu ejemplo será:

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

Resultados en 64bit Linux con 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

Por razones de integridad, también hay identificadores para scanf, cuyos prefijos son SCN.

Otros consejos

El valor de retorno de sizeof es un size_t. Si estás usando un compilador compatible con C99, parece que puedes usar %zd % zu para esto.

D'oh: % zu (sin firmar), por supuesto. Gracias, solo.

En primer lugar, debes hacer coincidir el "% " Especificador con el tipo de datos real que desea imprimir. sizeof devuelve el tipo de datos size_t , y al igual que no debe intentar imprimir un flotante con un "% d " especificador, no debe intentar imprimir un size_t con "% u " o "% d " o cualquier cosa que realmente no signifique size_t.

Las otras respuestas han brindado algunas buenas maneras de manejar esto con compiladores más nuevos ("% z " y PRIu32), pero la forma en que solíamos hacerlo era simplemente convertir size_t en un archivo sin firmar, y luego imprimirlo usando "% lu " ;:

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

Esto no funcionará en sistemas donde size_t es más ancho que un largo, pero no conozco ninguno de estos sistemas, y ni siquiera estoy seguro de si el estándar lo permite.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top