And Arduino seems to be a mixture of C and C++, which makes it confusing as to which standard(s) it supports. But I learned my lesson, at least for now
.
Yes. Arduino – and most other current microcontroller development environments – is based on a mix of
freestanding C and
freestanding C++. This limits the language features that are available. For C, it means the standard library may not be available at all, or is incomplete. For C++, it means things like exceptions are not supported. Arduino provides its own libraries, but also happens to provide a mostly complete C library (typically avr-libc or newlib) for most microcontroller targets. They do not document this well, though. (Not a surprise: the C standard defines
freestanding pretty well, but the C++ standard uses quite vague "whatever the provider provides" -like wording. Basically, we're reaching outside well-standardized environments here.)
Besides, Arduino does quite interesting mangling to the C/C++ source .ino files, before feeding them to the compiler!
For Teensyduino:
For Teensy 2.0 (ATmega32u4) and 2.0++ (AT90USB1286), we have avr-libc. The features it provides are listed *
here*. Do note that only the parts actually used from the library are included in firmwares.
For Teensy LC, 3.x, 4.x (all 32-bit ARM based ones), the gcc-arm-none-eabi toolchain is used; it includes newlib. The features it provides are listed *
here*, but do remember to skip the syscall stuff (they're only relevant when running under an actual operating system, and with Arduino/Teensyduino, we're running on bare hardware instead). There is also some other stuff there that isn't used here, like environment, most of stdio.h, and so on.
Because GCC is used as the compiler, we also have some rather interesting stuff available that it provides. We have
function attributes that can help the compiler optimize code better;
variable attributes;
integer overflow built-ins, and
other built-ins – the bit ones can be particularly useful (ffs, clz, popcount, parity). If one generates complex state machines, then the
labels-as-values extension GCC provides can be especially useful, as it allows one to obtain labels (goto targets) as void pointers, for use in state machine descriptions (actions or transitions to goto to).
Teensy 4.0 and 4.1 and Micromod also have VFPv5 (VFPv5-SP-D16, I believe), which can do additions and subtractions (including saturating ones) on four 8-bit, two 16-bit, or one 32-bit value stored in a 32-bit register. (I have not checked which version of GCC is needed for these to be available via the
vector extensions.) It includes hardware (single precision?) floating point unit, including fused multiply-adds (and -subtracts, -negates), minimum and maximum, and even square root. This means that basic arithmetic (addition, subtraction, multiplication, division, and square root) using the 'float' type is quite efficient.
One can implement the most critical parts of the code in
extended asm, too. While this uses assembler (GNU as) syntax, we can leave the exact register selection to the compiler, and thus "seamlessly" join C and assembly code. (I might use them to expose the saturating integer math instructions as C functions one could call, for example.)