quitar - libreria para acentos en c++
Operador de Tilde en C (4)
Cuando pasa un argumento a printf
y ese argumento es de tipo entero más corto que int
, se promueve implícitamente a int
según las reglas de promoción de argumentos de K & R. Por lo tanto, su printf
impresión se comporta de la siguiente manera:
printf("%u/n", (int)~i);
Tenga en cuenta que este es un comportamiento indefinido ya que le dijo a printf
que el argumento tiene un tipo unsigned
mientras que int
es en realidad un tipo firmado. Convierta i
en unsigned short
y luego en unsigned
para resolver el comportamiento indefinido y su problema:
printf("%u/n", (unsigned)(unsigned short)~i);
unsigned short int i = 0;
printf("%u/n",~i);
¿Por qué este código devuelve un número de 32 bits en la consola? Debe ser de 16 bits, ya que el short tiene 2 bytes.
La salida es 4,294,967,295 y debería ser 65,535.
Es porque los argumentos para printf()
se ponen en la pila en palabras, ya que no hay forma de que printf sepa que el argumento es corto. Además, al utilizar el formato %u
solo indica que está pasando un número sin firmar.
N1570 6.5.3.3 Operadores aritméticos unarios p4:
El resultado del operador ~ es el complemento bit a bit de su operando (promovido) (es decir, cada bit en el resultado se establece si y solo si no está establecido el bit correspondiente en el operando convertido). Las promociones enteras se realizan en el operando y el resultado tiene el tipo promocionado. ...
El tipo entero más pequeño que int
se promueve a int
. Si sizeof(unsigned short) == 2
y sizeof(int) == 4
, el tipo resultante es int
.
Y lo que es más, el especificador de conversión printf
%u
espera unsigned int
, por lo que la representación de int
se interpreta como unsigned int
. Básicamente le mientes al compilador, y este es un comportamiento indefinido.
%u
espera un unsigned int
; si desea imprimir una unsigned short int
, use %hu
.
EDITAR
Lundin tiene razón en que ~i
seré convertido a tipo int
antes de pasarlo a printf
. i
también se convierte a int
en virtud de pasar a una función variadica. Sin embargo, printf
convertirá el argumento de nuevo a unsigned short
antes de imprimir si se utiliza el especificador de conversión %hu
:
7.21.6.1 La función fprintf
...
3 El formato debe ser una secuencia de caracteres multibyte, que comienza y termina en su estado de cambio inicial. El formato se compone de cero o más directivas: caracteres multibyte comunes (no%
), que se copian sin cambios a la secuencia de salida; y especificaciones de conversión, cada una de las cuales da como resultado la obtención de cero o más argumentos subsiguientes, convirtiéndolos, si corresponde, de acuerdo con el especificador de conversión correspondiente , y luego escribiendo el resultado en el flujo de salida.
...
7 Los modificadores de longitud y sus significados son:
...
h
Especifica que el siguiente especificador de conversiónd
,i
,o
,u
,x
oX
aplica a un argumentounsigned short int
short int
ounsigned short int
( el argumento se habrá promocionado de acuerdo con las promociones enteras, pero su valor se convertirá enshort int
ounsigned short int
antes de imprimir ); o que un especificador de conversiónn
siguiente se aplica a un puntero a un argumentoshort int
.
Énfasis mío
Entonces, el comportamiento no está indefinido; solo sería indefinido si i
o ~i
no fueran tipos integrales.