I wrote a little output stream class in a previous post: C++ write your own stream class - part 1: output stream initial design (embedded friendly C++) .
In this post, I'm adding an input stream, and an input / output stream that's subclass based on the previous 2. Goal is to show that using C++, objects, and derived children, and using streaming, has exact the same cost as C code.
C++ design: stream data with objects
This is a C++ example that uses a class hierarchy, to (hopefully) show that classes, when used wisely, come for free.

#include <string>
class uartostream {
public:
uartostream() {}
uartostream& operator << (const char* msg) {
// write to UART
volatile char c = msg[0]; //this is the example code
return *this;
}
uartostream& operator << (const std::string& msg) {
// write to UART
return *this;
}
};
class uartistream {
public:
uartistream() {}
uartistream& operator >> (std::string& msg) {
// read from UART
return *this;
}
uartistream& operator >> (char* msg) {
// read from UART
return *this;
}
};
class uartiostream: public uartistream, public uartostream {
};
int main() {
uartiostream u;
u << "5" ;
}
This is example code. The goal is to show how expensive it is to instantiate an uartiostream object, and to stream a char string to it.
I did a few things to make it possible to compare it to plain C code:
- I used a char array, because that's a data type that also can be used in C. Sheep vs sheep.
- in the method that gets called, I avoided that the optimiser removes the code, by setting a variable to volatile. In that case, the compiler doesn't optimise that variable away, and keeps the code lines where it is used in place (although it is alklowed to optimise those code lines.
C code for performance comparison
The simplest C equivalent is this:
int main() {
volatile char c = "5"[0];
}
I tried to make the smallest C code that performs the same function as the C++ code. Assign the first char of a char array (the same "5" as in the C++ code) to a volatile variable of type char.
Verdict
The GCC compiler generates exactly the same assembler for both cases - C single line and C++ with embedded aware inheritance. I tested it for ARM and RISCV:
#ARM 32 (same for the C and C++ program)
main:
mov r3, #53
mov r0, #0
sub sp, sp, #8
strb r3, [sp, #7]
add sp, sp, #8
bx lr
#RISC-V 32 (same for the C and C++ program)
main:
addi sp,sp,-16
li a5,53
sb a5,15(sp)
li a0,0
addi sp,sp,16
jr ra
This shows that you can use C++ and objects in embedded design. And that the cost of abstraction can be low (or in this case zero).
![]() |
![]() |

