Hacker News new | ask | show | jobs
by pknopf 3039 days ago
Let me ask it this way:

I'm a higher level programmer. Later in my career I happen to get down to microcontrollers, what would stop me from using C++?

5 comments

The standard library (with all its' duplicate code resulting from hardcore templating) will blow up your flash space usage significantly, to the point where you will run out of it sooner than you expect. You will spend time finding alternative standard libraries that are size-optimized and you might end up rewriting a lot of what you take for granted in your C++ daily usage. For example, the Arduino environment is C++-based, but it's not anything like on the desktop due to it not shipping an std:: .

Your typical heap-happy usage will not go down well on a microcontroller, either. Having very constrained RAM makes heap fragmentation much more of an issue.

Then don't use the standard library. Don't even link it in.

> Your typical heap-happy usage

Huh? 1990s C++ was typically heap-happy, which is part of the reason Java looks the way it does. Idiomatic modern C++ uses the stack as much as possible. And one can use custom allocators.

Not a good fit for systems with small hardware stacks - PIC16 is still in use http://www.microcontrollerboard.com/pic_memory_organization....
A lot of people do. But they may as well not. They tend to write C-style C++.

Simply put, because you can't use the STL, or a lot of other C++ features, or only with a lot of consideration.

A whole swathe of the embedded world still cares about program size in bytes. There are some that don't, but they tend to be using Linux, and are at a higher abstraction level than many others in the industry. (Industry is kinda divided in half. Those who use tiny Linux machines, and those working with microcontrollers. It's a generalization, but generally fits.)

The stuff I work on day-to-day, usually has between 1-4kb for dynamic memory, and 8-16kb for the compiled program. That line is also usually a bit blurry, and you can move things between both at runtime, but at various costs.

With C++, you get tempted to use stuff like vector, which can blow your memory stack.

I generally work with C++, but it looks like C. I get a few things like implicit pointers, for free, but generally still have to end up making most things explicit.

But, unlike twenty years ago, I no longer have to dive into assembly unless the project is pushing it's limits. The compiler tends to be "good enough".

It really depends how you use it. If you are approaching from the standpoint of "I am writing code on a microcontroller", which means no exceptions, no static initializers, probably no templates, definitely no rtti, then it will be all okay. If you approach it from the standpoint of "I'm just programming, how hard could it be? Let's just use std::", you're going to have a very bad time and very quickly.

C++, when used in that way, tends to do a lot of things behind the scenes. This is perfectly okay in a place where you have an operating system and a linker that have your back. On an embedded system none of this is guaranteed.

Static initializers and templates are great in a deeply embedded context, IMO.
For you yes, since you know how they are implemented at linker level. But get a few junior devs on your team, and you'll be wondering why hundreds of thousands of cycles run before main is called, or why some driver code is being entered before it is initialized, since someone decided to make a static singleton object for some driver and called some driver method in the constructor which will run before main(), not realizing how this stuff really works underneath.

So, C++ can be a wonderful tool in proper hands, but it is much easier to misuse than C in an embedded context.

If you let junior programmers fuck up your codebase that much, that's not the junior's fault. You should do code reviews.
I lead a team of six, including some junior devs.

How initialization occurred (static or otherwise) was just something we made an explicit check off item in code review.

Awesome. Glad it worked out for you. I hope it stays so after you leave the team or no longer have time for each code review.
Constexpr init can also be great in that case To initialize rom with complex objects.
note, static initializers works in embedded you need to execute functions between __init_array_start and __init_array_end before using any static object in gcc somewhere in program
I'm well aware of that. But giant array of static Constructors makes it hard to reason about when any piece of Hardware is accessed since a lot of stuff happens before Main (). Especially for people who don't play with the insides of linkers for fun on weekends.
Sorry that sounded like i'm scorching you i didn't mean it. Yes agree with when using HW initializing code in constructors I ended with two types of 'constructors/inits': 1 - for object initialization 2 - just for hardware and calling manually :/.
Nothing. I've worked on Cortex-M4 projects in C++. It's nice in many ways. The people working on the project had a much more diverse background than the typical EE who learned C as an undergrad mentioned in another thread.
Not much. The Arduino programming environment is really gcc in C++ mode, but a different library.