Tengo un código C ++ que imprime un size_t:
size_t a;
printf("%lu", a);
Me gustaría que esto se compilara sin advertencias en arquitecturas de 32 y 64 bits.
Si esto fuera C99, podría usar printf("%z", a);. Pero AFAICT %zno existe en ningún dialecto estándar de C ++. Entonces, en cambio, tengo que hacer
printf("%lu", (unsigned long) a);
que es realmente feo.
Si no hay ninguna facilidad para imprimir size_tmensajes de correo electrónico integrados en el lenguaje, me pregunto si es posible escribir un contenedor printf o algo así que inserte las conversiones apropiadas en size_tlos mensajes de correo electrónico para eliminar las advertencias falsas del compilador mientras se mantienen las buenas.
¿Algunas ideas?
Editar Para aclarar por qué estoy usando printf: tengo una base de código relativamente grande que estoy limpiando. Usa envoltorios printf para hacer cosas como "escribir una advertencia, registrarla en un archivo y posiblemente salir del código con un error". Podría reunir suficiente C ++ - foo para hacer esto con un contenedor cout, pero prefiero no cambiar todas las llamadas warn () en el programa solo para deshacerme de algunas advertencias del compilador.

"%l"? ¿No será siempre del tamaño correcto? ¿O importa la portabilidad?Respuestas:
La mayoría de los compiladores tienen su propio especificador
size_typtrdiff_targumentos, Visual C ++, por ejemplo, usa% Iu y% Id respectivamente, creo que gcc le permitirá usar% zu y% zd.Podrías crear una macro:
Uso:
fuente
%zes compatible o no, depende del tiempo de ejecución, no del compilador.__GNUC__Por lo tanto, usar es un poco problemático si mezcla GCC / mingw con msvcrt (y sin usar la printf aumentada de mingw).El
printfespecificador de formato%zufuncionará bien en sistemas C ++; no hay necesidad de hacerlo más complicado.fuente
C ++ 11
C ++ 11 importa C99, por lo que
std::printfdebería admitir el%zuespecificador de formato C99 .C ++ 98
En la mayoría de las plataformas,
size_tyuintptr_tson equivalentes, en cuyo caso puede utilizar laPRIuPTRmacro definida en<cinttypes>:Si realmente quieres estar seguro, envía
uintmax_ty usaPRIuMAX:fuente
En windows y la implementación de printf de Visual Studio
funciona para mi. ver msdn
fuente
VS 2008también. También tenga en cuenta que se puede usar%Id,%Ixy%IXtambién.Ya que está usando C ++, ¿por qué no usar IOStreams? Eso debería compilarse sin advertencias y hacer lo correcto con reconocimiento de tipos, siempre que no esté utilizando una implementación de C ++ con muerte cerebral que no defina un
operator <<forsize_t.Cuando la salida real se tiene que hacer con
printf(), todavía se puede combinar con iostreams para conseguir un comportamiento de tipo seguro:No es súper eficiente, pero su caso anterior trata con E / S de archivos, por lo que ese es su cuello de botella, no este código de formato de cadena.
fuente
std::stringstreamlugar de transmisiones IO.printf("x=%i, y=%i;\n", x, y);vscout << "x=" << x << ", y=" << y << ";" << std::endl;.aquí hay una posible solución, pero no es muy bonita ...
fuente
La biblioteca fmt proporciona una implementación portátil rápida (y segura) de
printfincluir elzmodificador parasize_t:Además de eso, es compatible con la sintaxis de cadenas de formato similar a Python y captura información de tipo para que no tenga que proporcionarla manualmente:
Ha sido probado con los principales compiladores y proporciona resultados consistentes en todas las plataformas.
Descargo de responsabilidad : soy el autor de esta biblioteca.
fuente
El tipo efectivo subyacente a size_t depende de la implementación . C Standard lo define como el tipo devuelto por el operador sizeof; aparte de no estar firmado y ser una especie de tipo integral, size_t puede ser prácticamente cualquier tamaño cuyo tamaño pueda acomodar el valor más grande que se espera que devuelva sizeof ().
En consecuencia, la cadena de formato que se utilizará para size_t puede variar según el servidor. Siempre debe tener la "u", pero puede ser l o d o tal vez algo más ...
Un truco podría ser convertirlo en el tipo integral más grande en la máquina, asegurando que no se pierdan en la conversión y luego usar la cadena de formato asociada con este tipo conocido.
fuente
size_ts al tipo integral más grande en la máquina y usar la cadena de formato asociada con este tipo. Mi pregunta es: ¿Hay alguna manera de hacer esto mientras mantengo el código limpio (advertencias solo para errores legítimos de cadena de formato de printf, sin cambios desagradables, etc.)? Podría escribir un contenedor que cambie la cadena de formato, pero luego GCC no podría darme advertencias cuando legítimamente estropeé mi cadena de formato.Más adelante en el código:my::printf("test ", 1, '\t', 2.0);fuente