O enigma dos tamanhos: por que int e long se comportam de forma diferente em compiladores distintos?
\n\nTodo mundo que estudou C++ a sério, mais cedo ou mais tarde, se deparou com este quebra-cabeça. Você escreve um código simples:
\n\n#include <iostream>\n\nint main() {\n std::cout << "Tamanho de int: " << sizeof(int) << " bytes\\n";\n std::cout << "Tamanho de long: " << sizeof(long) << " bytes\\n";\n std::cout << "Tamanho de long long: " << sizeof(long long) << " bytes\\n";\n return 0;\n}\n\nExecuta no seu notebook — obtém 4, 4, 8. Executa em um servidor Linux — 4, 8, 8. E em um sistema antigo de 16 bits (sim, eles ainda existem!) — 2, 4, 8. Qual é o truque? Por que o C++, uma linguagem famosa por seu poder e controle, permite tanta incerteza?
\n\nA resposta é simples e complexa ao mesmo tempo: o padrão C++ deixa deliberadamente os tamanhos dos tipos inteiros a critério da implementação. Isso não é um bug, mas uma característica que permite que a linguagem funcione em qualquer hardware — de microcontroladores a supercomputadores. Mas para o desenvolvedor, isso significa uma coisa: se você escreve código portável, não pode confiar em tamanhos específicos.
\n\nVamos entender o que o padrão C++ realmente garante (do C++98 ao C++23) e como não cair na armadilha da dependência de plataforma.
\n\nO que o padrão C++ garante? Tamanhos mínimos e hierarquia
\n\nEm vez de dizer "int tem 4 bytes", o padrão estabelece faixas de valores mínimas e uma hierarquia estrita de tamanhos. Aqui estão as regras principais do rascunho do padrão (seção [basic.fundamental]):
\n\n- \n
- Tamanho mínimo de
char: 1 byte (8 bits, embora formalmente um byte em C++ possa ser maior). \n - Hierarquia de tamanhos:
sizeof(char) ≤ sizeof(short) ≤ sizeof(int) ≤ sizeof(long) ≤ sizeof(long long). \n - Bits mínimos:\n
- \n
short: pelo menos 16 bits. \n int: pelo menos 16 bits. \n long: pelo menos 32 bits. \n long long: pelo menos 64 bits (adicionado no C++11). \n
\n - Tamanho de
int: o padrão recomenda queinttenha o "tamanho natural" para a arquitetura alvo (geralmente 4 bytes em sistemas de 32/64 bits). \n
Observe: long pode ser igual a int (no Windows de 32 bits) ou a long long (no Linux de 64 bits). Isso é totalmente legal!
Exemplo prático: teste no seu sistema
\n\nExecute este código e compare os resultados com colegas de diferentes sistemas operacionais:
\n\n#include <iostream>\n#include <climits> // para INT_MAX, LONG_MAX etc.\n\nint main() {\n std::cout << "Tamanhos em 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\nVocê verá que no Windows (MSVC) long geralmente tem 4 bytes, enquanto no Linux (GCC/Clang) tem 8 bytes. Esta é uma fonte clássica de bugs ao portar código entre plataformas.
Por que o padrão não fixa os tamanhos? Contexto histórico
\n\nImagine os anos 1970. Os processadores eram de 8 bits, 16 bits, e os de 32 bits estavam apenas surgindo. Os criadores do C (e