Selección de tipo para valores numéricos literales en C

Me pregunto sobre esto: cuando bash asignar un valor entero a una variable int (comstackdor de 16 bits, 2 bytes para enteros) digamos:

 int a; a=40000; 

eso no se puede representar con el rango del tipo que se truncará. Pero lo que veo es que el valor resultante en a es el patrón de bits para -25000 (o un número cercano), lo que significa que la representación binaria que el comstackdor elige para el decimal 40000 era una representación entera sin signo. Y eso plantea mi pregunta: ¿cómo elige el comstackdor el tipo para esta expresión literal?

Supongo que utiliza el tipo capaz de manejar el valor con menos espacio de almacenamiento necesario.

El comportamiento aquí difiere entre C89 y C99.

En C89, un literal entero decimal toma el primero de estos tipos en los que se puede representar:

 int, long, unsigned long 

En C99, un literal entero decimal toma el primero de estos tipos en los que se puede representar:

 int, long, long long 

Para su fragmento de código en particular, no hace ninguna diferencia, ya que se garantiza que 40000 encaja en un largo tiempo, pero hay algunas diferencias significativas entre los literales C89 y C99.

Algunas de esas consecuencias se describen aquí:

http://www.hardtoc.com/archives/119

De Kernighan & Ritchie , Apéndice A2.5.1 (Constantes enteras), p. 193:

El tipo de una constante entera depende de su forma, valor y sufijo … Si no tiene sufijo y es decimal, tiene el primero de estos tipos en los que se puede representar su valor: int, long int, unsigned long int.

Tenga en cuenta que esta respuesta solo es relevante para C89, ya que la segunda edición del “Lenguaje de progtwigción C” es anterior al estándar C99.

40000 en hexadecimal es 0x9C40. Observe que el bit más significativo de este valor es un 1 (0x8000). Suponiendo una representación de complemento a dos , eso significa que si metes 0x9C40 en una representación firmada, al restar el valor del bit de signo del rest, obtendrás 0x1C40 – 0x8000 = -0x63C0 = -25536 (base 10).

Echa un vistazo a INT00-C. Comprenda el modelo de datos utilizado por su (s) implementación (es) e INT02-C. Comprenda las reglas de conversión de enteros en el Wiki estándar de encoding segura CERT C para obtener más información.