rotacion manipulacion ejemplos desplazamiento derecha corrimiento binario c types printf c99 format-specifiers

manipulacion - ¿Por qué no se adoptaron nuevas cadenas de opciones de formato printf() en el ancho de bits como parte de C99?



manipulacion de bits pdf (5)

Mientras investigaba cómo hacer cadenas de formato printf() multiplataforma en C (es decir, teniendo en cuenta la cantidad de bits que espero que deba ser cada argumento entero printf() ), encontré esta sección del artículo de Wikipedia en printf() . El artículo describe opciones no estándar que se pueden pasar a cadenas de formato printf() , como (lo que parece ser una extensión específica de Microsoft):

printf("%I32d/n", my32bitInt);

Continúa afirmando que:

ISO C99 incluye el archivo de encabezado inttypes.h que incluye varias macros para su uso en la codificación printf independiente de la plataforma.

... y luego enumera un conjunto de macros que se pueden encontrar en dicho encabezado. Mirando el archivo del encabezado, para usarlos tendría que escribir:

printf("%"PRId32"/n", my32bitInt);

Mi pregunta es: ¿me estoy perdiendo algo? ¿Es esta realmente la forma estándar de C99 para hacerlo? Si es así, ¿por qué? (Aunque no me sorprende que nunca haya visto un código que use las cadenas de formato de esta manera, ya que parece tan engorroso ...)


Correcto, así es como el estándar C99 dice que debes usarlos. Si desea un código verdaderamente portátil que sea 100% compatible con los estándares de la letra, siempre debe imprimir un int usando "%d" y un int32_t usando "%"PRId32 .

Sin embargo, la mayoría de las personas no se molestarán, ya que hay muy pocos casos en los que el hecho de hacerlo no importe. A menos que esté transfiriendo su código a Win16 o DOS, puede asumir que sizeof(int32_t) <= sizeof(int) , por lo que es inofensivo int32_t accidentalmente un int32_t como un int . Del mismo modo, un long long es casi universalmente de 64 bits (aunque no se garantiza que lo sea), por lo que imprimir un int64_t como un long long (por ejemplo, con un especificador %llx ) también es seguro.

Los tipos int_fast32_t , int_least32_t , et al., Casi nunca se usan, por lo que puede imaginar que sus especificadores de formato correspondientes se usan aún más raramente.


La justificación de C parece implicar que <inttypes.h> está estandarizando la práctica existente:

<inttypes.h> se derivó del encabezado del mismo nombre que se encuentra en varios sistemas de 64 bits existentes.

pero el resto del texto no escribe sobre esas macros, y no recuerdo que fueran prácticas existentes en ese momento.

Lo que sigue es solo especulación, pero educado por la experiencia de cómo funcionan los comités de estandarización.

Una ventaja de las macros de C99 sobre la estandarización del especificador de formato adicional para printf (tenga en cuenta que C99 también agregó algunas) es que proporciona <inttypes.h> y <stdint.h> cuando ya tiene una implementación que admite las funciones requeridas en una implementación específica Así es simplemente escribiendo dos archivos con typedef y macros adecuados. Eso reduce el costo de hacer que la implementación existente sea conforme, reduce el riesgo de romper los programas existentes que hicieron uso de las características específicas de la implementación existente (la manera estándar no interfiere) y facilita la adaptación de los programas conformes a la implementación que no tienen estos encabezados (pueden ser proporcionados por el programa). Además, si las formas específicas de implementación ya variaron en el momento, no favorece una implementación sobre otra.


Otra posibilidad: compatibilidad con versiones anteriores. Si agrega más especificadores de formato a printf , u opciones adicionales, es posible que un especificador en algún código anterior a C99 tenga una cadena de formato interpretada de manera diferente.

Con el cambio de C99, no está cambiando la funcionalidad de printf .


Sólo puedo especular sobre por qué. Me gusta la respuesta anterior de AProgrammer, pero hay un aspecto que se pasa por alto: ¿qué agregará a printf como modificador de formato? Ya hay dos formas diferentes en que se usan los números en una cadena de formato printf (ancho y precisión). Agregar un tercer tipo de número para decir cuántos bits de precisión hay en el argumento sería genial, pero ¿dónde lo colocará sin confundir a la gente? Desafortunadamente, una de las fallas en C es que printf no fue diseñado para ser extensible.

Las macros son terribles, pero cuando tienes que escribir código que sea portátil en plataformas de 32 y 64 bits, son una bendición. Definitivamente salvé mi tocino.

Creo que la respuesta a tu pregunta es por qué

  • Nadie podría pensar en una mejor manera de hacerlo, o
  • El comité de normas no pudo ponerse de acuerdo sobre cualquier cosa que sintieran que era claramente mejor.

Siempre puede lanzar hacia arriba y usar %jd que es el especificador de formato intmax_t .

printf("%jd/n", (intmax_t)(-2));

intmax_t para mostrar que se puede usar cualquier intXX_t , pero simplemente hacer long es mucho mejor para el caso int32_t , luego use %ld .