9

When using C/C++ on other platforms, the int type is typically 4 bytes (or potentially more). However, on Arduino, it's only 2 bytes.

Why is it different? Does it affect performance if I always use the 4 byte long instead?

  • 2
    note that int is 4 bytes on the Arduino Due. A short will be 2 byte on all existing Ardunios, but I emphasize the others' advice to use int16_t or uint16_t. – Ron Feb 21 '14 at 6:18
10

The ATmega328 used in a lot of Arduinos is a 8-bit microcontroller. This means that registers are 8-bits, the data bus is 8-bits, the ports are 8-bits. There are some minimal 16-bit aspects to the system (e.g. one of the timers), but nearly everything is 8-bits.

Therefore, most operations handle 8-bits at a time. Working on anything except 8-bits (i.e. 16-bit or 32-bit integers and floating point numbers) requires what could essentially be described as software emulation, where the compiler uses multiple instructions to work on these larger variables.

8-bits is obviously adequate to address a 8-bit port. It's also enough to deal with many loop counters, return values, and ASCII characters. It isn't really enough though when dealing with numbers. A signed 8-bit int (int8_t) can only represent -128 -> +127. Unsigned (uint8_t) can only represent 0 -> 255.

8-bit integers are quite limiting. C/C++ int must represent at least -32,678 -> +32,767 so maps to int16_t - the smallest size that will do so. This gives a good balance of range and efficiency. This is especially important when beginners are learning - overflow is not really something that non-programmers understand.

There is a performance impact of doing this however, because most 16-bit operations take at least twice as long as an 8-bit operation, and use twice as many registers. This may or may not make a difference to you.

Many of us switch to the native types such as int8_t and uint8_t as it gives you far more control.

  • 3
    Just a note: it's not the Arduino Team that mapped int to int16_t, "int" is a C/C++ reserved keyword, and the type mapping is part of the ABI (gcc.gnu.org/wiki/avr-gcc) that the avr-gcc compiler's developers decided to follow. Another notably difference is in the "double" type that usually is 64bit wide, while in the avr-gcc is 32bit like "float" – cmaglie Feb 20 '14 at 15:09
  • Thanks. Not sure why I wrote that. I know int must represent 32,678 -> +32,767 (though, actually, I think there was a proprietary compiler for one of the NEC processors that didn't follow this). I think it is because I don't like hiding widths on embedded systems - using int16_t is much clearer. – Cybergibbons Feb 20 '14 at 15:25
  • 1
    +1 for the use of clear native types! On the Arduino Due, an int is 32-bit! arduino.cc/en/Reference/int – Ron Feb 21 '14 at 6:13
3

One important fact about C and C++ languages is that their respective standards do not define the size (in bytes) of integral and floating point number types.

They just define minimal ranges and relation between these ranges, e.g.

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

So the size of e.g. an int will typically depend on:

  • the target platform (processor)
  • the compiler itself
  • are you saying sizeof(short) == sizeof(int) == sizeof(long) is possible? – Ron Feb 21 '14 at 6:09
  • @ron-e Theoretically, yes, that would be possible. In practice, however, I've never seen that. In most compiler/platforms, one could expect (although it is not imposed) that sizeof(short) < sizeof(long). – jfpoilpret Feb 21 '14 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.