Bom, dias atrás um colega virou pra mim e perguntou:
- Quantos bytes tem uma variável float?
Respondi de bate-pronto:
- Depende... Mas na maioria dos casos são quatro.
E mostrei pra ele um velho truque para saber quantos bytes um tipo de variável ocupa (em C):
printf("%i",sizeof(float)); /* troque o float para o tipo desejado */
Então, em 99% dos casos você vai ver que o float ocupa quatro bytes (32 bits). O grande problema em C é o tal do int, que depende do processador e/ou do compilador. Normalmente o pessoal que programa para PC não se preocupa muito com isso, mas para sistemas com microcontroladores pode dar uma dor de cabeça quando for salvar a variável (numa EEPROM por exemplo). A melhor opção é não usar int. Não custa nada incluir a inttypes.h e usar os tipos dela (int8_t, uint8_t e por aí vai) ou criar os seus próprios typedefs num canto qualquer.
Pois então, depois da pergunta fiquei curioso e resolvi testar alguns compiladores e sistemas diferentes. O programa de testes é este:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #include <stdio.h> |
As linhas 6 e 7 são pra mostrar a quantidade de bytes dos int e float. Incluí logo depois (linhas 9 e 10) um teste para os ponteiros para estes mesmos tipos. Claro que os ponteiros ocuparão a mesma quantidade de bytes, mas vai que alguém resolveu inventar moda. Nunca se sabe...
Para começar, o bom e velho Dev C que mantenho instalado e uso quando preciso gerar um programinha rápido. E o resultado foi este:
Ele usa o GCC 4.8.1 para 64 bits e o resultado foi 4 bytes para int e float e 8 bytes para os ponteiros. Testado no Windows 7 de 64 bits. Aí vemos que o int não segue o número de bits do sistema, parece que ele vai ficar nos 32 bits mesmo.
Agora os testes com compiladores online, via browser (como é bom viver no futuro):
No primeiro caso o jdoodle deu nó (warnings) com o %i no printf, mas funcionou direitinho (o sizeof retorna um int). E junto com o Codingground deu o mesmo resultado do Dev C.
Dos compiladores online o que deu uma pequena diferença foi o Codechef com ponteiros de 32 bits:
Um sistema diferente que testei foi o Nios II da Altera, numa plaquinha chinesa com uma FPGA Cyclone IV (já tinha tudo ligado e instalado no PC):
O NIOS II pode ser definido como um "microcontrolador por software" e o teste confirma a sua natureza de 32 bits.
E nos microcontroladores? Como não queria perder tempo ligando uma placa e instalando uma IDE resolvi testar no CodeWarrior 6.3 que tenho instalado numa máquina virtual com windows XP. Nele eu posso simular o software sem precisar gravar numa placa.
Usei o Wizard dele e gerei um programa mínimo com o Processor Expert:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| /* Code Warrior */ int var_int,var_float,pointer_float,pointer_int,res; void main(void) { /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ /* Write your code here */ /* For example: for(;;) { } */ for(;;) { var_int = sizeof(int); var_float = sizeof(float); pointer_float = sizeof(float*); pointer_int = sizeof(int*); res = var_int + var_float + pointer_float + pointer_int; } } |
Salvei os resultados dos sizeof em variáveis para aparecer no simulador e a soma ali na linha 21 é só pra ele gerar o código. Sem ela o CodeWarrior dá um de esperto e não compila as linhas anteriores, já que não serviriam pra nada.
Algo interessante é que numa das telas do wizard dá pra escolher o tamanho do double, mas não o tamanho do float (ou não tem ou é IEEE32):
No primeiro teste selecionei um microcontrolador MC9S08QE128 de 8 bits:
E tá lá o float de 32 bits (4 bytes). O interessante (e esperado) são os ponteiros para 16 bits. Já o int são dois bytes.
Agora passando para Coldfire V1 (MCF51QE128 de 32 bits) a tela do wizard muda e temos a opção do float e double de 64 bits.
Eita, temos um problema aí. Eu selecionei o float de 64 bits, mas ele saiu com 32 bits. Provavelmente um erro na tela do wizard. Os ponteiros são de 32 bits, de acordo com a arquitetura dos Coldfires. Era pra testar com o CodeWarrior para Coldfire V2, mas ele está instalado num HD antigo e não quis abrir meu PC pra fazer o teste.
Acho que já ficou claro então que o float é de 32 bits e o int varia. Mas fiz um último teste, com o saudoso Turbo C. Como vivemos no futuro posso rodar o compilador ancião diretamente no browser:
O Turbo C é do tempo do DOS e o resultado não poderia ser outro:
É igual ao do microcontrolador de 8 bits da Freescale: int de 2 bytes, float de 4 e endereços de 16 bits. Era assim nos tempos anteriores ao Pentium.
No CCS o.int usa 8 bits.
ResponderExcluir