uber - tipo promoción en C
que poner en un curriculum en habilidades (3)
El estándar C explica esto bastante claramente (§6.5.6 Operadores aditivos):
Si ambos operandos tienen un tipo aritmético, las conversiones aritméticas habituales se realizan sobre ellos.
(§6.3.1.8 Conversiones aritméticas habituales):
... las promociones enteras se realizan en ambos operandos.
(§6.3.1.1 Booleano, caracteres y enteros):
Si un
int
puede representar todos los valores del tipo original, el valor se convierte en unint
; ... Estas se llaman promociones enteras. Todos los otros tipos no se modifican por las promociones enteras.
Como int
puede representar todos los valores de uint16_t
en su plataforma, a
y b
se convierten a int
antes de que se realice la resta. El resultado tiene tipo int
, y se pasa a printf
como int
. Has especificado el formateador %u
con un argumento int
; estrictamente hablando, esto invoca un comportamiento indefinido, pero en su plataforma el argumento int
se interpreta como representación de complemento a dos, y eso se imprime.
Estoy bastante confundido por el siguiente código:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char ** argv)
{
uint16_t a = 413;
uint16_t b = 64948;
fprintf(stdout, "%u/n", (a - b));
fprintf(stdout, "%u/n", ((uint16_t) (a - b)));
return 0;
}
Eso vuelve:
$ gcc -Wall test.c -o test
$ ./test
4294902761
1001
$
Parece que la expresión (a - b) tiene el tipo uint32_t. No entiendo por qué ya que ambos operadores están uint16_t.
¿Puede alguien explicarme esto?
Si tira los bits de un número de la parte superior (mediante el molde explícito a un entero sin signo de 16 bits), entonces tendrá un resultado que es más pequeño (dentro del rango de 0 y 2 ^ 16-1) que antes de.
C promueve los argumentos a unsigned int
antes de hacer la resta. Este es un comportamiento estándar.
Véase, por ejemplo, en una expresión C donde están presentes unsigned int y signed int, ¿qué tipo se promocionará a qué tipo? para detalles.