Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:52

Liste des GroupesRevenir à cl c 
Sujet : Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:52
De : david.brown (at) *nospam* hesbynett.no (David Brown)
Groupes : comp.lang.c
Date : 17. Mar 2026, 10:37:39
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <10pb7d3$2pm55$1@dont-email.me>
References : 1
User-Agent : Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0
On 17/03/2026 08:09, Oguz Kaan Ocal wrote:
Hey guys,
 
You might also be interested in the comp.arch.embedded group.  It is not as popular as comp.lang.c, but there are a number of folks who quietly follow the group in case interesting questions turn up.

I've been debating this with myself for a while now. When you're working on resource-constrained hardware, do you guys actually use the standard C library (libc) or do you go full Bare Metal for everything?
 
I use some of the standard library in my bare-metal (or small RTOS) coding.  The freestanding, or function-free headers are of course in heavy use - I have <stdint.h> <stdbool.h> in pretty much every file. (The latter is now unnecessary with C23.)  Small utility functions, like memcpy and string functions, are also fine in almost every system. Typically a good compiler will inline many of those uses directly rather than calling a library function.
Like most serious small-system embedded programmers, I avoid any use of malloc/free except in very specific and controlled circumstances.  Even then, I usually use specially written dynamic memory functions.
 From the printf family, snprintf is the most common choice.  For smaller systems I'll often have specifically written conversion routines for output (typically a debug UART connection).  For bigger systems, I'll often use snprintf to do the formatting for convenience.  Yes, the printf family has overhead in code size and runtime.  If that overhead is too big for the target, I don't use it - if it is small enough not to matter, I /do/ use it.  There is no fixed rule.  (For many toolchains, you can choose between a (sn)printf that has floating point support, and one that does not - if you don't need floating point output, especially if the target does not have floating point hardware, picking the non-floating point version can save a large amount of code space.)

I'm talking about things like using sprintf() vs. writing your own itoa(), or malloc() vs. static buffers. Even a simple printf() can bloat the binary by several KB and eat up the stack like crazy.
 A few things I'm curious about:
 Does anyone here still use the full standard library on chips with <32KB Flash? Or is it an immediate "no-go" for you?
 
Nobody /ever/ uses the full standard library, in any code, on any system.  You only ever use the parts of the library that make sense to the code you are writing.  That applies whether you are programming for a data centre or for a tiny microcontroller.
Basically, if the C library has a function that does the job you need, and the overhead (due to features you don't need) is not too high, use that function.  There are no fixed rules.  And in embedded systems your code typically does not need to be highly portable, so feel free to use additional functions provided by your toolchain and its library.
There are parts of the C library that rarely make any sense on small systems - the file I/O functions, signals, wide characters, signals, most maths functions, etc.  There are parts that are generally fine (but read the small print!) such as the mem* and str* functions.  Memory management is always a big concern, so generic malloc/free are often not a good idea.  The big thing to be wary of, however, are the atomics and thread functions in C11 - these are often either useless or far worse than useless in embedded toolchains.

For string manipulation (memcpy, memset, etc.), do you trust the compiler's built-in optimizations or do you write your own assembly/manual loops to save those extra cycles?
 
It is a /long/ time since I have felt my hand-written assembly does better than the compiler.  But it can depend on your target.  If you still have to deal with brain-dead 8-bit CISC devices, manual assembly can sometimes be faster (but "faster" is not the only meaning of "better").  For decent microcontrollers - 32-bit ARM Cortex-M being massively dominant in the market - you are unlikely to do better than the compiler in any meaningful way.  Of course, you do have to have a basic understanding of the compiler and how to work with it to generate efficient results.  If you don't enable optimisations, or use appropriate target flags, or write the code in a way that can lead to good generated code, then your end results will be poor.
Note that it is fully possible to view the generated assembly code.  In situations where speed is critical and each cycle counts, I always examine the generated assembly, and if necessary adjust my C code or use additional compiler features until I am happy with the assembly.  That is a more flexible and maintainable solution that writing the assembly directly.  If I do need to write assembly, I do so with absolute minimal inline assembly code that can be optimised within the C code (at least with gcc).  In fact, most inline assembly code I use is actually empty, but exists to force particular effects in gcc.

How do you handle things like dynamic memory? Is malloc() ever acceptable in a mission-critical embedded loop, or is it always static allocation only?
Malloc is rarely acceptable in real-time embedded systems - at least for the important stuff.  /Maybe/ you can use it in connection with logging or debugging code.  The real problem is not malloc, but free - it is not uncommon to see embedded systems where the "malloc" implementation is just a stack, and "free" does not exist.  If you really need dynamic memory (and you often do for things using Ethernet or Wifi networks), you will often want a specialised setup with allocation pools for different purposes.

 I feel like using the standard library is "cheating" and adds too much hidden overhead, but rewriting every basic utility feels like reinventing the wheel.
 What's your take? Do you prefer the portability of standard C or the lean-and-mean performance of custom bare-metal implementations?
I use what does the job in a way that I know is correct and efficient enough for the task at hand.  There is no single universal answer.  As for portability, I don't make code unnecessarily non-portable (within reason - there's usually no need to be obsessive about code that works on /every/ system).  But I have no qualms about making code non-portable if there are advantages in doing so, and if attempts to compile the code on unsuitable systems will give a compile-time error.

Date Sujet#  Auteur
17 Mar 26 * Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:5219Oguz Kaan Ocal
17 Mar 26 +* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:522Bonita Montero
17 Mar 26 i`- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521Oguz Kaan Ocal
17 Mar 26 +* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:522Michael S
17 Mar 26 i`- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521Oguz Kaan Ocal
17 Mar 26 +* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:523David Brown
17 Mar 26 i`* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:522Oguz Kaan Ocal
17 Mar 26 i `- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521David Brown
17 Mar 26 +* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:525Janis Papanagnou
17 Mar 26 i`* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:524David Brown
18 Mar 26 i `* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:523Janis Papanagnou
18 Mar 26 i  `* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:522David Brown
18 Mar 26 i   `- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521David Brown
17 Mar 26 +* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:524David Brown
17 Mar 26 i`* Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:523Bonita Montero
17 Mar 26 i +- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521David Brown
17 Mar 26 i `- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521Bonita Montero
17 Mar 26 +- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521Chris M. Thomasson
17 Mar 26 `- Re: Bare Metal C vs. libc: Is the overhead worth it on small MCUs?,08:521Waldek Hebisch

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal