But the same is true for C. There is a lot from the standard library you can't use. File I/O for example. Malloc & free are also troublesome to say the least.
No, "freestanding C" is very well defined compared to "freestanding C++". If you compare the standards, you'll find that C++ leaves it basically up to the implementation, which means that "freestanding C++" is implementation defined – it doesn't mean anything unless you specify the implementation.
For freestanding C,
none of the standard library is available. Facilities provided by <float.h>, <limits.h>, <stdarg.h>, <stddef.h>, <stdbool.h>, and <stdint.h> should be available. Complex number support is optional, and using any floating-point variables or operations can require special consideration (for example, on hardware that does not support FP), but otherwise the core language features are available. This is well defined, with few surprises.
For freestanding C++, some of the
core language features, like exceptions, may or may not be available; you don't know, unless you know the implementation. And Arduino folks don't say; they don't really even call the code C++, just "Arduino sketches".
It is true that the distinction between "freestanding" and "hosted" is crucial for C, but is often ignored because people think it is "obvious" from the context. I think that is equally misleading to new programmers.
But there are also standards defining some specific variant of a language, like C++17 (ISO/IEC 14882:2017) or C18 (ISO/IEC 9899:2018).
Exactly. And my point was that while "Freestanding C" is well defined in the standards with fuzzy edges around complex and floating-point support only, "Freestanding C++" is almost completely implementation-defined,
including core language features like exceptions.
There must be a limit to how many core language features you can remove, and still call it the same language. With C, you get mostly right if you say "the standard C library is not available", but with C++, all bets are off; and therefore a more descriptive label that much more important.
In the other direction, I've mentioned "POSIX C99", which means a hosted C99 (ISO/IEC 9899:1999) environment that provides IEEE Std 1003.1™-2017
System Interfaces.
(FWIW, I personally do point out to learners that
"Arduino uses a subset of C++ features, not the full C++ language" with additional descriptions of those features depending on their knowledge level. I do that because it is thus far it seems to foster the most reasonable expectations and helps with the intuitive grasp the environment. Those expecting their hosted C++ to be directly applicable are usually sorely disappointed by the limitations.)