upvote
I've been writing C++ for embedded systems the past year or two.

We use a very conservative subset of C++, almost like C with inheritance. We barely even use templates. We try to avoid allocating on the heap. The code is mostly imperative.

Since 2011, a lot of new language features have been introduced. The ones we use are things like smart pointers (that improve lifetime management) and some tweaks for better type safety.

It is said that moden C++ enables a functional programming style. I have never actually seen anybody code that way (it would be hell to write and worse to read) but that could just be the niche I'm in.

What is undeniable is that C++ is so complex and has so many features that you have to choose a subset of the language to enforce a consistent style.

Also a lot of the STL (standard library functions) are deprecated in one way or another, which is a real minefield.

reply
All modern C compilers are written in C++.

C also has dialects.

reply
Yes, we switched from C98 to C11 and are about to adopt MISRA C 2023 (with exceptions).
reply
The dialects issue is why I avoid interviewing in C++, because inevitably it turns out the interviewer has some weird view of what "C++" is and doesn't realize it. Years ago I had an interview in "C++14" that required std::optional (C++17) as implemented by a C++14 compiler with only experimental, nonstandard support. In another case, an interviewer on the LLVM team vehemently disagreed with me that you could legally implement std::atomic types with mutexes, as I was going over a story about fixing issues in an awful stdlib that implemented them with mutexes.

This kind of thing doesn't happen when I interview in other languages.

reply
It seems like the history of programming languages since the 1980s has mostly been people trying to avoid C++.

First languages with run-times and dynamic types, and more recently lower levels of abstraction (Go, Rust).

reply
I was there, and C++ was all over the place on Windows, OS/2, Mac OS, UNIX/CORBA.

It was FOSS with its set of coding guidelines, that gave C a new wind.

Languages with runtimes and dynamic types go all the way back to Lisp and Smalltalk.

reply
> Languages with runtimes and dynamic types go all the way back to Lisp and Smalltalk.

Java was the 800lb gorilla though, wasn't it? Because it promised portability.

Why did Smalltalk not take off?

reply
Java was the 800lb gorilla thanks to Sun's marketing.

Write Once Runs Everyone has been the promise of several bytecode formats since UNCOL in 1958, with UCSD Pascal being the most famous one until Java came to be.

Smalltalk was already taking off when Java came to be, it had a role similar to .NET on Windows, on OS/2, with SOM (OS/2's version of COM), doing C, C++ and Smalltalk.

All IBM Visual Age IDEs were written in Smalltalk, however it was exactly IBM alongside Oracle that were the very first to jump onboard to the Java ship.

Thus one day of the other, Smalltalk was out, and Java in.

Eclipse started as a rewrite from Visual Age into Java, and many of the Java early frameworks were ports from Smalltalk.

Also note that while Java has a C++ like syntax, its execution model is closer to Smalltalk and Objective-C, thus why it was such a great fit for Sun, acquiring StrongTalk and re-purposing the JIT compiler into Hotspot.

reply
== Long-ago, Smalltalk systems could be file-copied from say win to mac to unices and would just work.

== Not standardized. Language vendors used proprietary code to lock-in customers and that fragmented the skills base. Skilled Smalltalk-A programmers were not-so-skilled with Smalltalk-B.

== Not free as in beer.

reply
What was the disagreement on the atomics issue?

I only know them from openMP (more of a Fortran person)… without much thought my gut says that it’d be possible to implement an atomic operation with a mutex, but sort of defeating the purpose. An atomic operation is mostly expected (intended? hoped?) to be backed by some hardware atomic instructions anyway, right?

reply
They insisted that it wasn't legally possible and no one would ever do that, but std::atomic<T>::is_lock_free [0] exists precisely because implementers were doing it. The only case that anyone was ever likely to encounter AFAIK was atomic structs >= 16 bytes on MSVC because they couldn't use cmpxchg16b for reasons.

I had been using a truly awful stdlib on an embedded platform whose implementers saw that freedom as a license to implement all atomics with mutexes. I assume it was because they couldn't be bothered to write new implementations for every platform they supported, so they'd write the basic primitives and got the rest of the implementation "for free". This isn't even close to the dumbest decision they made.

Obviously that wasn't acceptable for any real use, so I wrote up a better implementation, sent it to the vendor as a patch to save their other poor customers the effort, and used it as a one line example in a larger list on my resume that the interviewer seized on. It's not uncommon for a FAANG interview to be adversarial like that.

[0] https://en.cppreference.com/cpp/atomic/atomic/is_lock_free

reply