El enigma de los tamaños: ¿por qué int y long se comportan de manera diferente en distintos compiladores?
\n\nCualquiera que haya estudiado C++ en serio, tarde o temprano se ha encontrado con este rompecabezas. Escribe un código simple:
\n\n#include <iostream>\n\nint main() {\n std::cout << "Tamaño de int: " << sizeof(int) << " bytes\\n";\n std::cout << "Tamaño de long: " << sizeof(long) << " bytes\\n";\n std::cout << "Tamaño de long long: " << sizeof(long long) << " bytes\\n";\n return 0;\n}\n\nLo ejecuta en su portátil y obtiene 4, 4, 8. Lo ejecuta en un servidor Linux y obtiene 4, 8, 8. Y en un sistema antiguo de 16 bits (¡sí, todavía existen!) obtiene 2, 4, 8. ¿Cuál es el truco? ¿Por qué C++, un lenguaje famoso por su potencia y control, permite tal incertidumbre?
\n\nLa respuesta es simple y compleja a la vez: el estándar de C++ deja deliberadamente los tamaños de los tipos enteros a criterio de la implementación. Esto no es un error, sino una característica que permite que el lenguaje funcione en cualquier hardware, desde microcontroladores hasta supercomputadoras. Pero para el desarrollador, esto significa una cosa: si escribe código portátil, no puede confiar en tamaños específicos.
\n\nAverigüemos qué es lo que realmente garantiza el estándar de C++ (desde C++98 hasta C++23) y cómo no caer en la trampa de la dependencia de la plataforma.
\n\n¿Qué garantiza el estándar de C++? Tamaños mínimos y jerarquía
\n\nEn lugar de decir "int son 4 bytes", el estándar establece rangos de valores mínimos y una jerarquía estricta de tamaños. Estas son las reglas clave del borrador del estándar (sección [basic.fundamental]):
\n\n- \n
- Tamaño mínimo de
char: 1 byte (8 bits, aunque formalmente un byte en C++ puede ser mayor). \n - Jerarquía de tamaños:
sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long). \n - Bits mínimos:\n
- \n
short: al menos 16 bits. \n int: al menos 16 bits. \n long: al menos 32 bits. \n long long: al menos 64 bits (añadido en C++11). \n
\n - Tamaño de
int: el estándar recomienda queinttenga el "tamaño natural" para la arquitectura objetivo (generalmente 4 bytes en sistemas de 32/64 bits). \n
Tenga en cuenta: long puede ser igual a int (en Windows de 32 bits) o a long long (en Linux de 64 bits). ¡Esto es completamente legal!
Ejemplo práctico: comprobación en su sistema
\n\nEjecute este código y compare los resultados con colegas de diferentes SO:
\n\n#include <iostream>\n#include <climits> // para INT_MAX, LONG_MAX, etc.\n\nint main() {\n std::cout << "Tamaños en bytes:\\n";\n std::cout << "short: " << sizeof(short) << "\\n";\n std::cout << "int: " << sizeof(int) << "\\n";\n std::cout << "long: " << sizeof(long) << "\\n";\n std::cout << "long long: " << sizeof(long long) << "\\n\\n";\n\n std::cout << "Valores máximos:\\n";\n std::cout << "INT_MAX: " << INT_MAX << "\\n";\n std::cout << "LONG_MAX: " << LONG_MAX << "\\n";\n std::cout << "LLONG_MAX: " << LLONG_MAX << "\\n";\n return 0;\n}\n\nVerá que en Windows (MSVC) long a menudo es de 4 bytes, mientras que en Linux (GCC/Clang) es de 8 bytes. Esta es una fuente clásica de errores al portar código entre plataformas.
¿Por qué el estándar no fija los tamaños? Contexto histórico
\n\nImagínese la década de 1970. Los procesadores eran de 8 bits, 16 bits, y los de 32 bits apenas estaban apareciendo. Los creadores de C (y