2009-03-31 16 views
5

Estaba buscando en la página de manual de printf y se me ocurrió algo. Me preguntaba si hay algún "abogado de idiomas" aquí que pueda responder a una pregunta relativamente simple :-P.pregunta acerca de los especificadores de formato de impresión incompatibles

Así que el modificador 't' se define como

La siguiente conversión entera corresponde a un argumento ptrdiff_t.

Entonces, ¿qué es supone que suceda si se combina esto con una conversión de entero sin signo? Está claro que o, u, xy X son todos interpretados como valores sin signo, mientras que d e i están firmados. También hay versiones con y sin firma para todos los modificadores (int/unsigned int, size_t/ssize_t, etc.) excepto ptrdiff_t.

En la práctica, no pasa nada malo ya que las versiones sin firmar de los tipos ocupan la misma cantidad de espacio que las versiones firmadas. Así que la derecha de bytes se saca de la pila.

Así que nada "malo" que ocurre, de hecho, en grabados el valor esperado para todas las cosas probadas, excepto el "INT_MIN" (suponiendo que sizeof(int) == sizeof(ptrdiff_t).

printf("%tu %td\n", INT_MIN, INT_MIN); 

impresiones

2147483648 -2147483648 

en una Sistema de 32 bits

¿La norma tiene alguna opinión al respecto? Me imagino que la respuesta será "comportamiento indefinido". Pero pensé en preguntar;).

+0

¿Tiene esto ¿Tiene algo que ver con C++ (al menos antes de C++ 0x)? ¿Se va a cambiar printf() etc. en C++ 0x para cumplir con C99? Creo que deberías eliminar la etiqueta C++. –

+0

ptrdiff_t se define en cstddef en C++. printf obviamente también existe en C++. No estoy al tanto de C++ 0x cambiando printf en absoluto. –

+0

hrmm, parece que C++ puede no tener el modificador c99 't'. Lo suficientemente justo. –

Respuesta

3

Nada que ver aquí. El código que has escrito es legal.

Sólo algunos hechos de por qué:

  • todos los tipos de enteros con signo tienen homólogos sin signo, con los mismos requisitos de tamaño/alineación
  • ptrdiff_t se prescribe para ser un tipo entero con signo por la norma. Por lo tanto, tiene un gemelo sin firmar. (De hecho, la lógica similar se aplica a size_t así - ssize_t no es C, pero POSIX)
  • la t longitud especificador debe trabajar con d, i, o, u, x, X tipos
+0

¿cuál es el equivalente válido sin signo de ptrdiff_t? – user83255

+0

No tiene un nombre especial; solo puede decir que si ptrdiff_t es "long long", entonces su contraparte sin signo es "unsigned long long", etc. – jpalecek

+0

El hecho importante que ha omitido es que, en los casos en que el valor se ajusta tanto a las variantes firmadas como a las no firmadas de un tipo entero, tiene la misma representación y el estándar permite explícitamente pasar el tipo de argumento "incorrecto" en este caso (que solo es posible para funciones sin prototipos y funciones variadas, de todos modos). Por lo que puedo decir, sería UB para pasar un valor 'ptrdiff_t' negativo cuando el especificador de formato espera un tipo sin signo. –

Cuestiones relacionadas