Por que int é apenas 2 bytes?

9

Ao usar o C / C ++ em outras plataformas, o inttipo geralmente é de 4 bytes (ou potencialmente mais). No entanto, no Arduino, são apenas 2 bytes.

Porque é diferente? Isso afeta o desempenho se eu sempre usar os 4 bytes long?

Peter Bloomfield
fonte
2
observe que inthá 4 bytes no Arduino Due. A shortterá 2 bytes em todos os Ardunios existentes, mas enfatizo os conselhos dos outros para usar int16_tou uint16_t.
Ron

Respostas:

10

O ATmega328 usado em muitos Arduinos é um microcontrolador de 8 bits. Isso significa que os registros são de 8 bits, o barramento de dados é de 8 bits e as portas são de 8 bits. Existem alguns aspectos mínimos de 16 bits no sistema (por exemplo, um dos temporizadores), mas quase tudo é de 8 bits.

Portanto, a maioria das operações manipula 8 bits por vez. Trabalhar em qualquer coisa, exceto 8 bits (ou seja, números inteiros de 16 bits ou 32 bits e números de ponto flutuante) requer o que poderia ser essencialmente descrito como emulação de software, onde o compilador usa várias instruções para trabalhar nessas variáveis ​​maiores.

8 bits é obviamente adequado para endereçar uma porta de 8 bits. Também é suficiente lidar com muitos contadores de loop, valores de retorno e caracteres ASCII. Não é realmente suficiente quando se lida com números. Um int assinado de 8 bits (int8_t) pode representar apenas -128 -> +127. Não assinado (uint8_t) pode representar apenas 0 -> 255.

Inteiros de 8 bits são bastante limitantes. C / C ++ int deve representar pelo menos -32.678 -> +32.767, para que seja mapeado para int16_t - o menor tamanho que o fará. Isso proporciona um bom equilíbrio de alcance e eficiência. Isso é especialmente importante quando os iniciantes estão aprendendo - o excesso não é realmente algo que os não programadores entendam.

Entretanto, há um impacto no desempenho de fazer isso, porque a maioria das operações de 16 bits leva pelo menos o dobro do tempo que uma operação de 8 bits e usa o dobro do número de registros. Isso pode ou não fazer diferença para você.

Muitos de nós mudamos para tipos nativos, como int8_t e uint8_t, pois oferecem muito mais controle.

Cybergibbons
fonte
3
Apenas uma observação: não foi a Equipe do Arduino que mapeou int para int16_t, "int" é uma palavra-chave reservada em C / C ++ e o mapeamento de tipo faz parte da ABI ( gcc.gnu.org/wiki/avr-gcc ) que o Os desenvolvedores do compilador avr-gcc decidiram seguir. Outra diferença notável é no tipo "duplo" que normalmente é de 64 bits de largura, enquanto no avr-gcc é de 32 bits como "float"
cmaglie
Obrigado. Não sei por que escrevi isso. Eu sei que int deve representar 32.678 -> +32.767 (embora, na verdade, acho que havia um compilador proprietário para um dos processadores NEC que não seguiram isso). Eu acho que é porque eu não gosto de esconder larguras em sistemas embarcados - usar int16_t é muito mais claro.
21418 Cybergibbons
11
+1 para o uso de tipos nativos claros! No Arduino Due, um inté de 32 bits! arduino.cc/en/Reference/int
Ron
3

Um fato importante sobre as linguagens C e C ++ é que seus respectivos padrões não definem o tamanho (em bytes) dos tipos de número de ponto integral e de ponto flutuante.

Eles apenas definem intervalos mínimos e a relação entre esses intervalos, por exemplo

range(short) <= range(int) < range(long)

Portanto, o tamanho de, por exemplo, um intnormalmente depende de:

  • a plataforma de destino (processador)
  • o próprio compilador
jfpoilpret
fonte
você sizeof(short) == sizeof(int) == sizeof(long)está dizendo que é possível?
Ron
@ ron-e Teoricamente, sim, isso seria possível. Na prática, no entanto, nunca vi isso. Na maioria dos compiladores / plataformas, pode-se esperar (embora não seja imposto) isso sizeof(short) < sizeof(long).
Jfpoilpret