Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C and C++ don't have good stories for working on embedded systems without a standard library?


Not in the language standard they don't, no. The C99 standard basically says "good luck with that":

"5.1.2.1 Freestanding environment

1. In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.

2. The effect of program termination in a freestanding environment is implementation-defined."

There are obviously numerous embedded toolchains that provide facilities for writing C/C++ to target embedded systems but they're generally all doing nonstandard things and every one is its own unique fork of GCC.


And that's all perfectly fine.

If I'm running embedded with no OS, I'm in a very specific environment. My code is going to be tied to my specific hardware, including almost certainly the specific CPU chip. (In this situation, it's usual to have a "CPU" chip that includes several peripherals on-chip, to reduce parts cost. Code is not portable to a CPU with different peripherals, even if it's from the same family.) So, if I can't reuse the code anyway, do I care that I can't reuse the one line that is the "main" function definition?

If I'm running embedded with no OS, what should happen if the program terminates by exiting main? Where is there to go?


We're going off into the weeds here but in C this is implementation defined. In Rust you can use `#[no_std]` and the semantics are all well-defined. There's a thriving Rust embedded ecosystem that's doing just fine. Yes, the specifics of interfacing with hardware are platform-specific, but the language and the `core` bits (under `std`) are well-known.


Those things are implementation-defined because anything else wouldn't make sense. If I'm making a C program for a microcontroller, I will need to know how that microcontroller works. It's probably an ARM core, which expects the first few bytes of flash memory to be a table which contains pointers to functions; it's my responsibility to put a pointer to my main function in that table.

This is completely unproblematic, and not really that different from having to make sure your code is compiled to a valid ELF file with the correct sections and section headers.

"Implementation defined" doesn't mean "nonstandard". A C program which overflows a signed integer is ill-formed, because signed overflow is undefined. A C program which relies on external linker scripts to set up the vector table and make the reset vector point to the main function is well-formed, it just necessarily depends on some implementation-defined behavior.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: