166 comments

[ 0.19 ms ] story [ 287 ms ] thread
[2018] but spiritually [1995].
Spiritually sometime in the 70s, I would say. Just one example:

     auto lim = atoi(argv[1]);
Use of atoi. And what if there is nothing at argv[1]?
Is Rust preferable for the embedded systems engineer who is primarily concerned with being modern?
Being modern for its own sake? I suppose it would be preferable, since Rust is newer and evolving rapidly. But if you're concerned with being employed and a wide variety of powerful tooling at your fingertips then C++ is probably a better bet. (Note: I am neither a C++ nor Rust developer, so I don't have a dog in this fight.)
Rust is always preferable.
On what merits?
Memory safety, build system, dependency management, the usual
It's just overall productivity.
Can you define productivity?
I can't speak for everyone, but I spent an unconscionable amount of time managing dependencies and libraries in C++. In Rust, it's the easiest part of my workflow.
You can speak for everyone. C++ dependency management is just...I don't even know where to begin.
> You can speak for everyone.

Not really. I only use header-only libraries and dependency management is a breeze for me. I check each library out as a git submodule into a third-party subdirectory in my project directory, point the includes path at it and off I go. When I want to upgrade, I pull the git tag/branch/commit I want and recompile. Its pretty simple.

I mean that's cool but you are definitely working against the language as opposed to having the language support you. Also this works nicely for self contained dependencies, and much less nicely for not self contained dependencies.
> you are definitely working against the language

How so?

> Also this works nicely for self contained dependencies, and much less nicely for not self contained dependencies.

Doesn't matter. You said: "You can speak for everyone." which is simply not true, as I have outlined. You didn't say anything about not self contained dependencies or whatnot. The person you replied to said "I spent an unconscionable amount of time managing dependencies and libraries in C++" and I... well, don't. So clearly not everybody does.

Right, but not all problems can solved with header only frameworks.
I did use Bullet physics not too long ago, which most definitely isn't header-only, but the exact same approach worked there too. Git submodule, set include path. The only difference is that I also told my build tool to build its sources and package them into an .a archive, which I linked against. It was no trouble at all.
Too late to edit: yes, I know this doesn't work for everything and won't work for everyone, but its worked great for me, so my point is simply that your assertion that everyone has difficulties dealing with dependencies is false. Some people for sure do, but there are people, like me, who don't.
What would be best is libraries that can be added with a one-liner of an include statement, then there's no more dependency management needed.
For example, I almost never need to use a debugger or Valgrind with Rust. Mysterious memory corruption just isn't a thing. Memory leaks are not a problem either (even though technically Rust doesn't claim to prevent all leaks, it does well enough in practice).

Rust catches data races, use of non-thread-safe functions, and use-after-free problems across the entire codebase, including (mis)use of 3rd party libraries, at compile time. I can add `.par_iter()` to a loop, and if it compiles, I know it doesn't mangle any data. If it doesn't compile, the compiler points me to the exact struct that needs a refcount, or a mutex, or atomic. That saves me weeks of chasing heisenbugs.

In debug builds it checks all integer arithmetic for overflow (no need to wrap types in custom class, works for dependencies too). This has saved my ass a few times.

There's a pretty decent standard library, and a good number of quality dependencies that can be installed with a 1-liner. If I need to (de)serialize a struct from JSON, it's a couple of lines. I want to switch that to msgpack instead, 2-line change. I need that compressed? 2 lines again, plugs in easily, and supports serialize-and-compress without an intermediate buffer.

Build system uses convention over configuration, so there's no artisanal "build script" to manage, or even an argument which build system sucks less. Dependency management and workspaces work well enough that it's practical to modularize projects into smaller libraries, and actually reuse them. Unit testing is built-in. Doxygen-like generator is also built-in, no config needed. Of course any language can do the same, but having zero friction removes excuses and really helps making people actually use these things.

It's just such a step-up that it's not even comparable.
Is there anything C++ does better at this point? Outside of compatibility, that is.
Too bad there is no first-class production ready GUI library for Rust that I can use for embedded systems.

Qt and C++ it is then.

And on the context of Windows IoT, UWP is all about .NET and C++, with the Rust bindings pretty much still doing baby steps.
Why is "being modern" a concern? Luckily, embedded is not the web, where 5000 frameworks sprout over lunch. I've never heard of anyone in embedded caring about being modern. Only about solving the problems efficiently. So i am curious: why do you ask?
Embedded engineering seems to be a lost art in the America. The typical American programmer is certainly not an embedded engineer, and our industry and American universities focus mainly on the application layer of both practice and theory. My university's[a] computer architecture and operating systems courses are both taught entirely using simulation, either simulated hardware or virtual machines, and we would certainly never write our own bootloaders or really ever put code to the metal. It all seems more Shenzhen than Silicon Valley, like part of the stack is simply a bygone thing of the past for American software engineers.

Neither C nor C++ could be considered new languages, and this seems to contribute to this estimation of embedded engineering as a "lost art." C and C++ give a "here be dragons feeling," that only the best engineers can hope to avoid pointer pitfalls and memory leaks. I wonder if Rust's advances in programming language theory could alleviate this problem. The new generation of programmers I feel I belong to are comfortable with functional programming, advanced types, and facile tooling like NPM.

I have personally found embedded engineering underrated in American industry, both for fun and profit. If adopting modern practices leads to further embedded engineering adoption, that would be a worthwhile pursuit for individuals and our community. Perhaps this takes the form of Rust.

[a] Top 300 in global ranking, with a standard but not cutting edge computer science program unlike Stanford or CMU. Having gone to only one university I admit this confusion could simply be a failing of my own education.

Embedded has always been a "I learned this myself, while tinkering, then expanded my knowledge by tinkering more, and then by having a job doing something similar" kind of field. So that is not new.
Another significant difference in embedded development is that it's the intersection of electrical engineering and software development. Without an understanding of both disciplines, it's difficult to be effective in a professional setting. Understanding the hardware, which is almost always custom to your project, is a base level requirement to be able to write the software that will control it.
very true, i found a niche here (well 70% firmware but being able to understand and reason about the big picture of the rest) and really enjoyed it. seemed to have carved a niche out too troubleshooting basic hw level issues and delivering faster. highly recommend it to anyone who feels it isnt applicable
Would you mind naming your company? Or a high profile company in the same field as your work? I'd like to get a taste of the sort of work you do.
Embedded programming in C is a chore, because embedded code can be much trickier to debug. Writing C without bugs is a great deal of work, and very stressful. Debugging it when you don't is also very stressful.

Embedded programming in C++ is pure fun. The more modern your code is, the less room you leave for bugs: when it compiles, it mostly works. Where it doesn't, it shows up in your logic, not in random memory corruption.

I do a lot of static_asserts and small composable constexpr methods so that when I am wrong I get a compile failure. Actually with IDE's I get a little overlay telling me the error usually.

Constexpr methods seem perfect for embedded in a lot of ways too. Yes, I won't be touching real memory or ports, but I can ensure that the method isn't doing silly things either. Having a memory address class that filters on the proper operations and only allows them is awesome. Saw a good video on the topic recently too https://www.youtube.com/watch?v=fsMmh8F8uV0

Except that most devs don’t understand what their C++ code actually does at runtime and many try to be too clever and use too many features. I have seen spectacular failures regarding memory usage and copies, static initializers, even exceptions (just design your APIs without them!)

C++ code bases may have less buffer overflows and off-by-one errors but I don’t trust them unless they come with an extensive safety-net in the form of unit-tests with good coverage.

I think embedded programming is similar to games programming -- it’s difficult due to the performance constraints and niche skills required (low-level I/O, 3D graphics), but also relatively badly paid. Edit to add: admittedly for different reasons; in gaming I think it’s that the supply of programmers outstrips demand, as every other new graduate dreams of being a games programmer.

I think the cultural shift is partly just people voting with their feet and going where the money is.

America certainly has the engineering talent, it's really the manufacturing base that has been decimated. In some sense this migration was necessary for the iPhone and web app revolutions, Web 2.0. Perhaps we'll see embedded engineering and manufacturing return to America once web and mobile application development becomes over saturated. Already there seems to be a struggle for normal new grads to enter these fields.
Forget the word “modern” — its just a label and the word “orange” could just as well be used.

It refers to an approach that doesn’t worry much about how things were done in C and instead thinks about how to represent things cleanly and efficiently with the aim of faster development and fewer bugs.

I was an embedded developer for years and still write a lot of code in C++ because it results in fast code that is easier to write than if I tried in C.

One of mantras of the c++ committee is that you should pay (have overhead) for the stuff you don’t use. So I don’t try to write code that looks like C.

For embedded, i would have said C not C++. C is more prevalent still.

For some industries where security or correctness guarantees are necessary, you see things like MISRA C used rather than Rust (or cpp).

There's also the Ravenscar profile[1] for Ada and the SPARK language[2]. How those compare in marketshare to MIRSA C, I'm not sure, I'm not in that field, though I've enjoyed reading about them at a conceptual level.

[1] https://en.wikipedia.org/wiki/Ravenscar_profile

[2] https://en.wikipedia.org/wiki/SPARK_(programming_language)

[&] https://docs.adacore.com/sparkdocs-docs/Examiner_Ravenscar.h...

Anecdotally, everything I've seen (hardware drivers) has been in (MISRA) C or a subset of C++. Ironically, many of the alternatives require too much discipline to keep devs happy. MISRA C at least lets them pretend they're in their happy place.
ive been in the misra c realm a while and romanticized ada, spark, ravenscar profile etc. i think if you have a team and problem that can go 100% in on it, its unmatched (and some industries certainly do, aviation, autopilots, internal fuze controls etc..)
(I'm assuming you're coming from C and don't already know C++ because of the linked article) If the ecosystem that's available is sufficient for your needs on the platforms you care about and you're not interested in easy compatibility with a C/C++ codebase or your existing C knowledge, I would recommend Rust over C++ whenever possible (C is a different question since it fills a slightly different niche and doesn't really have a solid alternative yet imo). Rust has a much simpler and well-chosen set and interaction of features than C++, but it does that by dropping many of the compatibility constraints of C and C++ (and making assumptions that are easier to make in 2021 than 30+ years ago). Compiler errors also more honestly reflect the learning curve, so it can feel more punishing at the start, but has a shorter learning curve to reach functionally correct code, where with C++ you might easily have been using it for 10+ years and still learn you've been doing something wrong the whole time.

That's a big set of ifs, though. It's possible that the compiler errors are discouraging enough that C++ might feel like a more comfortable choice (I would encourage you to not let this be your reason unless you're just interested in solving a one-time problem). I keep checking in on Rust to see how small and dependency free I can get the compiled binary, and I usually need a mess of nightly features. The ecosystem is also still a mess. There are a few great libraries, but otherwise it's a minefield of 0.x releases for most dependencies (admittedly, some of the most important ones are autogenerated bindings where the version number is meaningless). Bindings are really easy to write with Rust, however, and it's one of the few languages that really gets that right, but it's nowhere near as convenient as calling/using C or C++ from C++. Most of these issues are consequences of C and C++ having the existing inertia, but it is what it is. Some people want to ship things and not join a community.

If you're trying to get a job or just learn: learn both. C++ isn't going to go away completely any time soon, but, with every month that passes, there are fewer and fewer technical reasons to justify starting a new project in it vs Rust. Choosing an inferior tool because it's the only one you understand might often be the correct choice, but it's not a choice you want to have to make.

Thank you for this thoughtful comment. It seems the present moment is a flux for embedded programming languages, there is still a choice to make. Maybe we will be discussing "Modern Rust for C++ Programmers" in a few decades on HN!
C++ is not only not going away, its usage is still growing very, very fast. More people pick up C++ for professional use in any given week than the total who are coding Rust at work today. That will be true next year, too. All of the highest-paying coding jobs use C++. That will be true next year, too.
I don't know that « being modern » should ever be a primary concern. Especially when it comes to embedded where stable features and APIs are important.

It's largely the realm of C, with some industries working in Ada/SPARK. In terms of its profile, Rust fits the bill for being a good system/embedded programming language some day, but I don't know if it's mature and stable enough yet to be what you'd pick for a really serious job.

As for C++, I don't really see the point if you don't have technical debt.

Some embedded standards like AUTOSAR, require C++ not C.
I'm not a systems engineer, I just do data analysis and algorithms that sometimes need to go really fast.

I only recently investigated rust, and was hugely impressed with it. I regret not investigating it earlier. Language support for ownership and lifetime of variables is such a huge step up for writing code. Trying to do this through as hoc conventions in C, or through RAII in C++, is a lot harder.

I haven't yet had a chance to write anything significant in rust beyond a few small test projects, but next time I want to beat Python performance on something I'll be using Rust instead of Cython or C or C++.

It gets real fun when "going fast" is less about the software and more about what's happening inside the chip!
I guess so. Some newer libraries, especially if they target "modern backend" stuff like webassembly, websockets, ... are written in Rust. When safety is a concern it could be really preferable.

But, say, if you don't have a good support for your platform Rust is not useful. Ditto for most existing codebases. And in any case I don't see why your primary concern should be being modern vs getting things to work well

Most places I’ve done embedded dev at have been C or C++. Actually all, with some Lua or assembler sprinkled in.

Debugging C++ when your compiler for weird target (SH4, or worse) contains bugs, or when you have some relaxed memory consistency model, is quite a challenge because mapping C++ to assembler is definitely non-trivial. C, even with heavy optimizations, is a breeze comparatively.

I would happily join a team that uses Rust in an embedded setting. It shows that they care deeply about doing better than average, and that probably means they are better than average in everything.

Mapping C++ to assembler is exactly the same as mapping C to assembler, for those operations the languages share. If you are coding reasonably, there aren't any other operations that happen at runtime. C++ does its heavy lifting, preventing bugs, at compile time.
For sure C++ does a lot of heavy lifting at compile time, which shows in poor compile and link times, although it is less of a problem today than 25 years ago since hardware performance has increased.

I don’t agree that C++ automatically prevents bugs, even though using e.g. RAII can help a bit and leads to maintainable code.

If you use exceptions (you probably shouldn’t) there is one more code-path out from your code. That together with constructors/destructors being called and using STL instead of more trivial data-structures often leads to a lot bigger assembler output to trawl through if you need to.

C++ doesn't "automatically" prevent bugs. You have to actually, you know, use it.

By STL I guess you mean std::string and std::vector. That is wholly optional. I would not use those in a small embedded project, except maybe at startup, and then with a custom, non-freeing bump allocator.

in my embedded experience (small scrappy teams in contracting) c99 is just barely common place. and very welcome. 99% covers everything I've done. but for absolutely huge mcus where rust is supported, rust is probably welcome and easier to fit
(comment deleted)
I spent a lot of years writing C++ code and really enjoyed it, it’s a fun language and you can pretty much do anything with it. But the problem I encountered with it was that it just became so wide in terms of features that you have a hard time keeping up - you can spend years using the language to build real software and then walk into a job interview and get demolished by all sorts of crazy stuff you didn’t even know existed. I remember purchasing the book “Modern C++ Design” by Andrei Alexandrescu and after reading it I realized it was time to find something else to do. It was an awesome book and I loved it, but all I did was work on trading systems and I knew I’d never be able to keep up with C++ interviews if that was the direction they’d be taking. But I still love the memories of working with it, so much damned fun.
> so wide in terms of features that you have a hard time keeping up

This is why I like the slightly more walled-in gardens of the JVM and CLR. For instance, when someone is talking about JSON serialization in C#, you could bet your life that they are referring to one of ~2 specific libraries and sets of methods.

It is a lot easier to build a community of shared understanding when everyone is playing the same game every day.

> For instance, when someone is talking about JSON serialization in C#, you could bet your life that they are referring to one of ~2 specific libraries and sets of methods.

I wouldn't bet on it, https://devblogs.microsoft.com/dotnet/try-the-new-system-tex...

Also try to talk about Java 17 to clueless group of devs still delivering stuff into production with Java 8 in 2021.

> Also try to talk about Java 17 to clueless group of devs still delivering stuff into production with Java 8 in 2021.

Id say it’s part cluelessness and it’s part that they just don’t care. They’re comfortable with 8 and don’t want to learn anything new (even if 8 is a slower runtime).

I fear that the community will never move on past 8.

You could say the same of people refusing to move beyond C89, Python 2, Perl 5,..... and that is the whole point of perceived complexity and current features of those languages in 2021.
> I wouldn't bet on it, https://devblogs.microsoft.com/dotnet/try-the-new-system-tex...

This would be the 2nd of 2 that I was referring to. The first would be Newtonsoft.Json.

Except this is a new API, not the 2nd one.

You have to modify code using System.Text.Json for the code generator based way, and it doesn't support all the features, enjoy the comments section.

> Except this is a new API, not the 2nd one.

> and it doesn't support all the features

I think there was a misunderstanding.

We do not use System.Text.Json because it doesnt support everything Newtonsoft.Json does. At no point did I intend to make the claim that these were somehow compatible implementations.

Our shop is stuck on Newtonsoft until Microsoft realizes that polymorphic deserialization is actually a really useful thing and not just a pedantic security concern.

You can take bits and pieces of C++ and never have to swallow the whole thing. I’ve kind of settled on C++11 as having all the tools I’d practically need. It’s got the right balance, IMO. If you’re interviewing somewhere that says they use every feature of the latest C++ in their software, run!
Ok but I'm not sure I could go back to compiling without modules.
(comment deleted)
What's the big deal with C++ being bloated (Linus, many experts don't like it) and I keep hearing that it has become unmangeable?

C++ doesn't force you to use everything it's got. Can't I just write basic C style procedural code in C++ and use OOP constructs if necessary? It is completely optional I think. Don't like templates? Don't use them. Set a policy in the team/company to avoid using advanced C++ features.

It’s not just about writing code though. If you want to properly read code you have to understand all the “advanced” features they have used.

I’m reasonably familiar with C++, but not so much with arcane template meta programs. I never write templates, but it still trips me up from time to time when I have to understand one.

(comment deleted)
I guess the messy ugly template headers could be hidden as compiler intrinsics, like in Go with its compiler blessed generics for standard containers. Or how C's printf is implemented as compiler magic instead of vardiac macros.

The complexity needs to be somewhere in the end. A charitable view would be that Cpp's approuch is more ... inclusive?

Yeah. All the arcane template stuff, even if I understand for sometime, you're bound to forget it as soon as you stop using it (which you probably should in most times).

It reminds me, every time I try to jump too implementation of some standard library method/class, it just seems like a completely different language to me. And C++ is the language I've most experience with.

Meanwhile, I jump to some Rust or Golang* standard library implementation, it makes perfect sense very quickly. Even though I just use them for hobby projects.

* Go is probably a bad example because it doesn't have any generics. But still love how much more approachable their stdlib code is.

A lot of that is that you have to protect against name collisions. You have things like c macro's so methods need to be wrapped in brackets{e.g (min)( a, b ); } and also internal names need to be prefixed with an underscore and start with a capital (e.g _Foo) as that is reserved.

The global namespace still exists so unqualified names that do not have a reserved id( eg _Foo ) cannot be used and need to be qualified (e.g ::std::(min)( a, b );). All this to protect against us.

Some codebases are easier to read, I would rank them from libc++, MS STL, libstdc++ is readability. libstdc++ also seems to have code all over the place and use far more inheritance for composition of things.

There is no reason to use "arcane template meta programs" anymore. That is all old-C++ stuff needed to work around missing language and library features. It has been literally years since I coded or even (visibly) used any template meta program construct.

That's not to say it doesn't exist in the implementation of the Standard Library. I just never have any need to see any of it.

Workable when you control the whole codebase, not so much when you have to deal with external dependencies or huge piles of legacy code that you're stuck with. I quite like writing C++ when it's just me or I have tight control, not so much when I have to deal with some of the large projects with code spanning 20-30 years of history and dozens of developers (some of which died before I even started my job) that I've worked on where it wasn't my call. Not that I have any specific traumatic experience in mind...

Admittedly such a situation is not entirely due to C++, but it didn't help. But again, I do quite like C++ especially nowadays.

I was thinking of that - I agree that's a problem. In my work, we have some basic dependencies and not much else - Boost libs and that's all.

May we should create a new subset of C++. It will be called C+.

> Can't I just write basic C style procedural code in C++

You can, but the bloat Linus is complaining about comes from the ability to do that. C is a real mess and is a large part of what is holding C++ back from being simpler (for both better and worse). C seems simple, but you lose a lot of abstraction ability when you use it.

C++ seems a lot more complex, but that complexity allows you to write abstractions that do exactly what you need. Modern C++ is the discipline that lets you write good abstractions, with exactly the control needed.

Don't take the above as some sort of statement that C++ would be simple with C - that is completely untrue. Only that C++ is moving to giving people the power to write the simple and powerful abstractions they need - but the nature of those abstractions are very complex and that cannot be avoided if you need to write them.

> use OOP constructs if necessary

THIS IS FALSE TO THE CORE! C++ is NOT about OOP. C++ is about writing the style that makes the most sense. OOP is good for a subset of problems, but a lot of problems can be solved better by not using OOP, and C++ supports that. If you think of C++ as C with classes you are making a large mistake.

(comment deleted)
Only takes a couple folks who want to use all the esoteric features of c++ at your workplace in a culture where nobody can tell them “no” (which is increasingly common) and big chunks of your codebase can evolve into unmanageable mess. Tbf i found the same to be true with Python but not with languages like Java, C# and especially Go
Go would be modern in 1992, not 21st century.

While C# is now on version 10, and Java on 17, if we account for the releases in 2021, the large majority of the world is still delivering .NET Framework (C# 6)[0] and Java 8 code into production.

When I use modern C# and Java, always need to give a mini-lecture on current state of the world.

[0] There are ways to use newer C# version in .NET Framework, but with some caveats.

Go 17 is being released in aug so clearly it’s almost as modern as java. I for one is jelly of innovative features such as gc tweaking whackamole and never expiring dns ttl default
Just wait for when Go 1.18 finally catches up with CLU, now that is blazing modern!
Avoiding the newer parts is the worst imaginable response.

If you write C code in C++, you will only have C code, and nothing better than C code. If you write Java code in C++ (which you can, and some do) you will only have Java code, and nothing better.

Leave the C parts behind. Leave the O-O parts behind. Lean into Modern C++, and reap the benefits of all the work put in to make the language better than C, better than Java (i.e. pre-C++98 plus GC), better than C++98, better than C++11, better than C++14, better than C++17.

Pointer arithmetic and inheritance are still occasionally useful; you can still wrestle in the mud. But if they show up in more than a few places in a program, you are Doing It Wrong.

I’m not convinced about your counter argument, let alone worst imaginable response.

All I’m saying is if a new feature is added to C++, it doesn’t affect me and I can choose to pick which features are useful. I can still keep it absolutely minimal. C with some useful libs, and occasional OOP.

Why this is the worst possible answer? Obviously it works for me, it makes sense to me and it is perfectly logical in my view.

Others have said the language bloat creates burden when you read other people’s code. That makes sense to me.

Care to elaborate more? If you want to harshly criticize, it’s fine but you need to say a bit more so I can understand where you’re coming from. I just see a bunch of rhetorical statements.

Nothing is added to C++ without demonstrating usefulness. There is no "language bloat". If you fail to find any of it useful, it can only be by not paying attention.

Yes, you can limit yourself to the C and Java subset, just as you can drive everywhere in first gear, can eat all your food raw, can crap in a hole. Just because you can does not make it a good idea. Objectively, the more your code looks like C, the worse it is, because you are inviting into it all of the flaws endemic to C code.

>> Nothing is added to C++ without demonstrating usefulness. There is no "language bloat"

"Bloat" doesn't require that the features are literally useless, merely that their usefulness doesn't justify their added complexity.

And for many people, a huge portion of C++ falls into this category.

Just look at the 18 different methods of initialization for an example of this. Or look at ranges, which seem to simultaneously be far more verbose than the alternatives in every other language, while having measurable negative impacts on compile times (that have spread throughout the stdlib, so even if you don't use them you have to pay for them). Ranges are certainly "useful" but the cost/benefit ratio is questionable.

Ranges had to be implemented without using the new language features that would make it easy and clean. Its authors had to use template-metaprogramming substitutes that are slow. As the language implementations catch up, the library can be upgraded and will get faster to compile.

There are new initialization modes that are simpler. The old ones still have to work. But you don't have to use the old ones anymore.

>> Lean into Modern C++, and reap the benefits of all the work put in to make the language better than C, better than Java (i.e. pre-C++98 plus GC), better than C++98, better than C++11, better than C++14, better than C++17.

Serious questions:

What subset of C++ is "Modern C++"?

Are there flags for C++ compilers to only allow modern C++ and generate warnings when non-modern C++ is used? (For example, if an older-style C++ idiom is used, the compiler might say: "use of Old_Idiom is deprecated. Consider using New_Idiom instead".)

I don't use much C++ and I have found the language daunting to learn because it is large, complex, and full of gotchas. A better subset that is enforced would help newcomers not get lost.

There are not such flags, but they would not be useful if there were. Real C++ programs link code of many different ages. Generally, you can only afford to make the new code, that you are writing now, the new way, and maybe modernize stuff immediately around it. The old stuff is typically well-exercised, and as long as it does its job you have no reason to touch it or, often, see it.

But it is for the new code that the most value is available.

Generally, if there are two ways to do something, and one appeared in a recent Standard, using that is usually the better choice. Cppreference.com helpfully tags each bit with when it appeared.

Regarding modern check flags: clang-tidy has its modernize-* flags
You could be Scott Meyers, write:

====================================================

1992. Effective C++: 50 Specific Ways to Improve Your Programs and Designs.

1995. More Effective C++: 35 New Ways to Improve Your Programs and Designs.

1998. Effective C++, Second Edition: 50 Specific Ways to Improve Your Programs and Designs.

2001. Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library.

2005. Effective C++, Third Edition: 55 Specific Ways to Improve Your Programs and Designs.

2010. Overview of The New C++ (C++11)

2010. Effective C++ in an Embedded Environment

2014. Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14 ====================================================

and you would not be able to understand modern C++ anymore...

"The Errata Evaluation Problem"

http://scottmeyers.blogspot.com/2018/09/the-errata-evaluatio...

"As you may know, I retired from active involvement in C++ at the end of 2015, and in the ensuing two and a half years, I’ve forgotten enough details of the language that I am no longer able to properly evaluate bug reports regarding the technical aspects of my books. C++ is a large, intricate language with features that interact in complex and subtle ways, and I no longer trust myself to keep all the relevant facts in mind. As a result, all I can do is thank you for your bug report, because I no longer plan to update my books to incorporate technical corrections. Lacking the ability to fairly evaluate whether a bug report is valid, I think this is the only responsible course of action."

Wow, what a response. Thank you for taking the time to reply and I think you did a far better job of summing up the challenge of being a “modern C++ programmer” than I could have dreamed of. I had no idea that Scott Meyers had bailed on the language, I’m honestly stunned to read that.
What is our option now? Rust? I love it but it is moving 5x the rate of c++. Static analysis may save us in this one. Good tools will tell you when you did something the "old" way. I'm not sure which part of our pipeline that is. Cppcheck, coverity or some clang checker probably.
I would love compiler options for enforcing better practices and prohibiting old style code (no using bare new/delete, stricter implicit casts, etc.) It wouldn’t fix everything but would go a long way.

It’s a little bit of a peeve of mine that people just decided on new languages instead. But it is what it is, and I am probably not knowledgeable enough to really judge.

You can think of C++17 as a new language which happens to be able to compile most C++14, C++11, and C++98 programs.

The trouble is, if every new version is _technically_ its own new language, and if you have to break compatibility a little, why not just break a lot and fix everything?

It's not like C++ was ever known for ABI stability anyway.

The benefit is that ability to compile that old code, even if it takes some flags or marking it unsafe or whatever.

There is a lot of old code that will never be rewritten but is still valuable, and I believe we will waste a lot of time just language-shifting entire ecosystems as new languages come and go.

Look at python 2 to 3. There are still packages out there on python 2 that haven’t been migrated. And thats mostly the same language!

(Note that my view is colored somewhat because I am a scientific programmer)

For those that don't want to upgrade, why not use a pinned compiler? Everyone else does this with other languages, and overall I think the benefits outweigh the costs.
Rust? I love it but it is moving 5x the rate of C++. Static analysis may save us in this one.

Yes. Rust is complicated, but the compiler is unusually good at telling you what you did wrong. Before it results in a crash.

The underlying problem with C/C++ is that it still doesn't have a decent array story. " char * " is so 1970s. That can't be fixed without breaking so much. All you can do is try to paper over the problem with templates. But the mold always seeps through the wallpaper. Look at the example in the original posting that reads:

    FILE* fp = fopen(fname.c_str(), "r");
There it is, access to a raw pointer. Why is that even allowed any more? You ought to have to wrap "Unsafe" around it, or something.*
Because it needs to support 40+ years of legacy code. What's wrong with the more modern array types?
Because the underlying OS API expects a char* as file name.
Rather, the underlying OS requires an array of bytes terminated by 0 which can be hidden behind a decent API. The type being poor at expressing this is not a limitation of the OS but of the C type system. E.g in zig this would be `[*:0]u8` which is "a pointer to a region of memory of unknown length terminated by a 0 sentinel value". It's still a pointer but nothing says the type system can't track more state around it.
So why isn't the Linux API properly encapsulated for C++? Rust does that.

C++ got off on a weird I/O direction. That

   file << item << item;
syntax never really caught on. Someone liked Currying too much.
> Why is that even allowed any more? You ought to have to wrap "Unsafe" around it

There have been a few different projects aiming to introduce 'proper arrays' into C, but they never get traction, even when carefully designed for good backward compatibility. C is seemingly just too resistant to change. Here's Walter Bright's suggestion. [0]

Aside: why is the word story so popular on Hacker News these days? We can just say C doesn't have decent arrays. We aren't discussing its history, we're discussing a specific technical facet of the language.

[0] https://www.digitalmars.com/articles/C-biggest-mistake.html

>Rust? I love it but it is moving 5x the rate of c++.

I'm not sure this is true. It has been a year since the last really significant change to the language, whereas C++ is adding Ranges, Concepts, Modules, and so on and so on. The pace of change has slowed way down in Rust and sped way up in C++, it almost feels like C++ is moving "faster" now or they are at least close to matching pace.

But a lot of the Rust efforts at the moment are really just closing holes in the language - things that you would expect to be able to do, but haven't been able to do due to compiler limitations. Generic Associated Types and Const Generics both kind of fall into that category. The rate of true "new feature" development is way down.

To clarify, Scott never was a practicing programmer, but a book writer who capitalized on quirky details of C++. As he explained, there is less need of such books nowadays due to the vast availability of resources on the web.
Right; direct to the point!

I never understood people's fascination for Scott Meyers books (and i own a lot of C++ books). I felt that it sort of clued you in to the microdetails/dark corners but failed to teach actual big picture programming using those same features.

To say Scott Meyers never was a practicing programmer but just someone who capitalized on quirky details of C++...

Its kind of like, saying Donald Knuth was never a Computer Programmer, but some old faculty professor, with too much time on his hands, who capitalizes on puzzles and the natural complexity of computational theory. :-)

It also does not address the core point of the post.

At the moment for C++ the scene goes like this:

- For every traditionally challenging feature/issue of C++ advocates will say it has already been fixed on the latest standard. So you always feel to be a proper C++ developer you have to be a "Modern C++ Developer"

- You are supposed to know and use the modern features of the language but also use it according to what I call "the C++ on top of C++" called the "C++ Core Guidelines".

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

I printed them last week and its a 498 pages PDF. So of course you will have wait and rely on compilers/linters keeping up with it.

https://docs.microsoft.com/en-us/cpp/code-quality/using-the-...

They are not done yet, and we will soon move to the next phase in complexity in the daily life of a C++ developer. Having to troubleshoot the correct implementation of these automated checks by the different automated tools.

Like many, I have to sometimes use C++ professionally. Every time I do, I feel like I am a candidate to the Darwin Awards.

I've commented regarding "bailing the language", i.e. it was as a writer, not as a developer. Scott mentions himself that he is not a dev, and there is nothing wrong with this:

https://www.artima.com/articles/the-most-important-c-booksem...

From the above linked article by Scott Meyers;

I’ll begin with what many of you will find an unredeemably damning confession: I have not written production software in over 20 years, and I have never written production software in C++. Nope, not ever. Furthermore, I’ve never even tried to write production software in C++, so not only am I not a real C++ developer, I’m not even a wannabe. Counterbalancing this slightly is the fact that I did write research software in C++ during my graduate school years (1985-1993), but even that was small (a few thousand lines) single-developer to-be-thrown-away-quickly stuff. And since striking out as a consultant over a dozen years ago, my C++ programming has been limited to toy “let’s see how this works” (or, sometimes, “let’s see how many compilers this breaks”) programs, typically programs that fit in a single file. (make? Who needs stinkin’ make?) My living is based on C++, but it’s not by virtue of the programs I write in it.

It’s not by virtue of any intimate association with the language’s standardization, either, because I’ve never been a member of the C++ standardization committee, I’ve never been on the committee’s mailing lists, and I’ve never attended any standardization meetings. My knowledge of the inner workings of the committee—including the things that have had a significant impact on it—is based on what I’ve read and heard from others. This means that I may be ignorant of important forces that shaped C++ as we know it, because those forces may have been felt only within the committee.

Wow! This answers many questions that i have had over the years.

Confession by Scott Meyers from the article linked by "zerr";

I’ll begin with what many of you will find an unredeemably damning confession: I have not written production software in over 20 years, and I have never written production software in C++. Nope, not ever. Furthermore, I’ve never even tried to write production software in C++, so not only am I not a real C++ developer, I’m not even a wannabe. Counterbalancing this slightly is the fact that I did write research software in C++ during my graduate school years (1985-1993), but even that was small (a few thousand lines) single-developer to-be-thrown-away-quickly stuff. And since striking out as a consultant over a dozen years ago, my C++ programming has been limited to toy “let’s see how this works” (or, sometimes, “let’s see how many compilers this breaks”) programs, typically programs that fit in a single file. (make? Who needs stinkin’ make?) My living is based on C++, but it’s not by virtue of the programs I write in it.

Donald Knuth wrote TeX and related tools which are huge/complicated software over and above his Algorithms/Computer Science Theory contributions. He stands alone in his greatness.

Scott Meyers is not even in the same league. He is a "consultant" (with all the good and the bad which goes with this profession) and in the same group containing the eXtreme Programming/Agile/Scrum crowd.

What other endeavor could you take a break for a few years and then come back and still basically be at the same place where you left off? Pro golfer? Concert pianist? Physicist?

Hell I forget what half my codebase does in a matter of weeks and have to go hunting through documentation.

This means that Rust can also die once an "Effective Rust" is published and the author retires!
Yes, and everyone should watch Scott Meyers's awesome presentation at a D conference with the title "The Last Thing D Needs". (tl,dr version: The last thing D needs is someone like him, really to be so insanely convoluted, as C++ is, as to need someone like him.) Link to the video: https://www.youtube.com/watch?v=KAWA1DuvCnQ
I think it is pretty obvious that Mr. Meyers never actually programmed / used C++ himself for any real projects. That he would abandon the language after only 2.5 years of nonuse makes sense to me.
If you build quality working programs that is what counts. Not that you can fly through some esoteric template shenanigans. When I being questioned by potential client we talk about what I've done and how (I design and build products usually from scratch). I also give references so people can check. If they start talking to me about can I write correct code in C++ or whatever other language right here I know I am in a wrong place. Normally such talk never happens.
I feel like I'm in the minority in not finding C++ complicated. C++ has gotten significantly LESS complicated c++11 and onward, I'd say. Inheritance hierarchies with private/protected/friends and virtual methods lead to significantly more complex codebases than flat templates and judicious use of constructors and destructors to handle things' lifetimes. When you've got a nice templated API, writing the client code almost feels like writing in a scripting language.

I'd say the only really hard part is understanding move semantics, but even then that's not really necessary and the verbiage on the internet is way too academic in that regard when it's really simpler in practice than it is when explained.

How much experience of C++ is required to understand that?
I guess being around since the language exists.

Just like looking at C# 10, Java 17, Python 3.9,... and making sense where the features or standard library calls came from.

If you have the luxury of making a clean break from old style C++, possibly. But, for example, in my case the only reason to touch C++ is precisely older stuff like native API’s. Because of that, I’m never writing purely modern C++. If I’m writing C++, it’s going to be a mixed bag of stuff with naked pointers, naked pointers to pointers, mallocs, and other fun stuff, meaning the subtle interactions between old and new features are always on my mind.
Just like other languages, C++ is not (that) complicated, if you happen to have full control of the code being written.

It is when you scale the team, or have a codebase that is being kept running since C++ exists, that the problems start.

However, to be fair and something that C++ haters tend to cleverly forget, trying to update a .NET Windows Forms application written in C# 2.0 into C# 10, Java 1.4 into Java 17 and so on, will face similar issues in complexity and language idioms.

Andrei also found something else to do after writing the book!
Same for me, same. I spent years writing trading engines in C and C++ and have been rejected real quick because I don't use some modern template feature. A lot of stuff like the newer memory model and auto pointers are awesome but some of that template stuff is not for me when I look at the thousands of lines of assembly language, or worse still, huge chunks of code the linker does not throw out and is actually gets executed. I think it's just a 'flex' to attract candidates for particular culture fit so maybe, as another comment pointed out, it's probably best to steer clear of places that don't care for your real world experience in the field.
> an array of strings is now stored in contiguous memory, which is great for memory cache hitrates, which often delivers whole factors of speedup.

How do they do that? As string lengths can vary. One way might be to store the continuous strings in memory and then maintain an array of pointers to those strings. But then we are back to pointers.

Searched google. Didn't find anything.

This is not an article written by someone that knows what they are talking about.
This is written by Bert Hupert, the founder of PowerDNS among other things. That's at least 20 years of solid C++ engineering work.
It's called the "short string optimization".
What he meant that if you have an array of strings that implement Small String Optimization AND those strings are short (i.e. below the threshold for Small String Optimization) THEN they'll be contiguous in memory.

But you can be smarter than that. As it happens, I just implemented "vector of strings" where all strings are contiguous in memory.

The code: https://github.com/sumatrapdfreader/sumatrapdf/commit/bc8311...

The basic idea is like you said: you keep strings contiguously in memory and maintain a separate array of pointers to each string. Except it's not a pointer but u32 index into that block of memory.

Even if those were pointers, not the u32 indexes, it would still be cache friendly.

The point is that strings are close together.

If each string was allocated with malloc() then you don't control where they are allocated.

In the worst case each string could end up in a separate cache line, which would be much slower if you were to iterate over all strings.

Pointers are not slow because they are pointers. Pointers are slow because (usually) they point to random locations in memory, incurring cache misses. Pointers that point to contiguous memory can be just as fast as that same memory being accessed via an array directly, as long as the data stays contiguous.
> as long as the data stays contiguous

The data will stay contiguous as long as it's constant/read only.

But as soon as you start to use it and change it for doing some real work, it will get scattered.

Honestly I never want to write C++ again. It's a horrible Frankenlanguage at this point. I wrote C++ for awhile at Google and Google uses a fairly subset of C++:

- No exceptions. Instead they had util::Status (open sourced as absl::Status [1]) and a union type util::StatusOr<T>. I don't believe there's a C++ equivalent for this yet. There's a draft proposal for std::expected [2] but it didn't make it into C++20. I'm not sure what the future is. After many years I truly believe exceptions are a false economy for error-handling;

2. Teams can't write their own templates. This is for good reason. There's almost certainly no good reason to do this and you'll probably screw it up what with correctly handling rvalue references (eg perfect forwarding [3]) and the like.

3. No mutable reference parameters. These are really an anti-pattern and can give the caller no clue that something is modified. Worse, if you allow them you'll find people forget to const their references so you don't actually know if they're modified or not. Even worse, the compiler doesn't know either so it limits optimization opportunities.

It wasn't perfect. For anyone in the know I'll just say "int/size_t" and leave it at that, as one example.

Here are some practical problems:

1. The language is incredibly complex. This makes tooling more difficult. It also means any large C++ shop will out of necessity limit the features allowed such that every shop using a different C++ dialect;

2. As much as we now (since C++11) have smart pointers, you'll still find yourself using raw pointers. You then get into the issues that arise from this, primarily using pointers after their lifetimes and documenting who owns what the pointer points to;

3. The focus on threading primitives. I am now firmly in the camp that if you ever manually create a thread, you've screwed up. The potential pitfalls and errors from doing so are just massive. Most of the time you don't need it either. You should be using higher concurrency primitives or, in a lot of cases, use a cooperative async-await model as you rarely ever need to write truly multithreaded code;

4. (This applies to C too) The fact that types are platform dependent mean you need to use translation layers. So the standards only say a short isn't longer than an int and a long isn't shorter than an int and that's it.

5. Even initializing a variable is complicated [4];

6. std::string vs char * interfaces. Fun fact: there was a time in Chrome when every keypress on the Omnibar resulted in >25,000 string copies.

7. The ability to use uninitialized memory.

8. Stack vs heap allocation is obviously useful but the complexity cost is just massive. Just look at lambda capture [5].

7. The learning curve for C++ is just huge and that entails a lot of useless knowledge (eg explicit constructors, default constructors, copy constructors, move constructors, copy constructors vs assignment operators).

Almost all the time you don't write code for performance. You write it to work and for the next guy to know what the hell is going on and it's this last one where I think C++ falls so short.

I've known too many self-proclaimed C++ experts who revel in the complexity of C++ and consider it a virtue. It's like it allows them to show everyone how smart they are by using some esoteric feature or relying on some non-obvious default (eg a bit like the Javascript semi-colon ASI egoists).

I just never want to touch it again.

[1]: https://abseil.io/docs/cpp/guides/status

[2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p032...

[3]:

Nobody at Google writes C++ code.

If you are drawing conclusions from what you saw at Google, you have opinions about some other language that only just happens to be compatible with a C++ compiler.

Chrome.
Chrome is coded in Google-C++, which is what cletus was complaining about. The rest of the world is not constrained to code like Google does.
This is obviously wrong. I work in YouTube and c++ is my primary language. Infact more code is being written in c++ than any other language at google
The point was about the castrated C++ dialect imposed by Google C++ style guide, which even goes against some of the C++ best practices as expressed by the C++ Core Guidelines.

In fact, AOSP has plenty of examples on how not to write C++ in this day and age.

Perhaps I didn't express this properly but I found Google's C++ dialect quite easy to work with, readable and intuitive because it banned things like exceptions, writing your own templates and no mutable reference function parameters.

Also I found the protocol buffers and RPC C++ bindings to be straightforward. YMMV.

Additionally the tooling reasonably pleasant (at least for "leaf" projects in the build system).

I know if I were starting a C++ project from scratch that after questioning my life choices that led me to this point, I'd just auto-start with Bazel, Abseil, Gflags, GLog and GTest. The whole thing would also have to work with CLion.

I do wonder what the int/size_t fiasco is about. If anybody has more context.
I'm assuming it has something to do with type casting, with there often being two problems when casting between int and size_t on many systems: one being that int is a signed integer type whereas size_t is unsigned, and the other being that int might be a 32-bit type while size_t is often (on 64-bit systems anyway) a 64-bit type.

For non-negative values less than 2^31, these will happily cast among themselves "correctly", but outside that range you will run into trouble.

As one example of what can go wrong, consider the following code, where we have a 32-bit int (signed) and a 64-bit size_t (unsigned):

size_t s;

int i;

s = 0x00000000f0000000;

i = s;

s = i;

printf("0x%lx\n", s);

We've first assigned to s a valid value for its range (but greater than or equal to 2^31), then assigned s to i, casting it to i's int type (hint: i is negative here because of the int type's sign bit), then assigned i's value back to s, casting it back to a size_t (hint: this performs sign-extension of the most significant bit). The final value of s, as printed by the last line above, you will find is 0xfffffffff0000000, which is not the original value we assigned!

Interesting, the talk to the small buffer optimization is wrong. Only libc++, clangs/llvm's standard library implementation that is used on macos/bsd's, is that large. MS STL and libstdc++ are around 15-16 bytes.

Nice property of the libc++ one is that a 64bit integer will fit into it without allocating

libc++ is the default C++ runtime on Android as well.
ooh I didn't think of that, thanks. I guess ios too.
"[C++] certainly has its good points. But by and large I think it's a bad language. It does a lot of things half well and it’s just a garbage heap of ideas that are mutually exclusive. Everybody I know, whether it’s personal or corporate, selects a subset and these subsets are different. So it’s not a good language to transport an algorithm—to say, "I wrote it; here, take it." It’s way too big, way too complex. And it’s obviously built by a committee.

"Stroustrup campaigned for years and years and years, way beyond any sort of technical contributions he made to the language, to get it adopted and used. And he sort of ran all the standards committees with a whip and a chair. And he said "no" to no one. He put every feature in that language that ever existed. It wasn't cleanly designed—it was just the union of everything that came along. And I think it suffered drastically from that."

  -- Ken Thompson, 2009
Source: https://en.wikiquote.org/wiki/Ken_Thompson#%22Coders_At_Work...
Bjarne's vision for C++ is well documented in "The Design and Evolution of C++". but naturally Ken Thompson is completely unbiased against C++, just like Linus Torvalds.

https://www.amazon.de/-/en/Bjarne-Stroustrup/dp/0201543303

Rather than resorting to ad hominem, could you point out where exactly Thompson was actually wrong?

Moreover, the criticism by Thompson and Torvalds refers to the use of C++ as a systems programming language. The language proved itself very efficient for application programming, including the browsers everybody is using.

Ken Thomson had no issues doing that when referring to Bjarne Stroustroup.

He is completely wrong, because his comments reveals a complete lack of understanding how ISO works, or worse, he does understand it and is doing a malicious comment to transmit his biased opinion.

Bjarne has the vote of one person, it doesn't matter how much he yells, screams, slashes the whip down the members back.

It is one single vote, and above all, unless he has some dark magic powers, he cannot multiply himself to attend all voting sessions.

>it was just the union of everything that came along

Garbage collection isn't in the language though some people wanted it. So it isn't a union of everything.

Not in the mark-and-sweep variant but certainly as ref-counting. And not only once!
It doesn't collect garbage with cycles, and proposals for that have been rejected in the past.
True, but technically it is still a GC algorithm.
Actually it is, as API introduced in C++11, and yes Bjarne was one of those that opposed to it, if I remember correctly.

However, since no one has made any use of it, and existing C++ GC's follow other schemes (Unreal, C++/ClI,...), there is a ISO C++23 proposal to remove it from the standard.

It is not just Bjarne that opposed GC - no compiler implemented it (or not a major one anyway).
People really need to stop pointing this out (it was sort of off the cuff said during an interview). Ken Thompson and Bjarne Stroustrup have some history just like Linus Torvalds and Andrew Tanenbaum did. All of them are giants and while there are some merits to aspects of their arguments, it is a logical fallacy to use them as "Appeal to Authority" which is just an excuse for lack of knowledge/thought.
I've never seen this quote before, but I've been using C++ as my main language since the early 90s and this matches my opinion of it EXACTLY.

C++ is a design-by-committee mish-mash language chokeful of everything that was ever thrown at it without any regard to how well it all fits together. In practice it is indeed used in a form of restricted feature subsets, because there's basically no other way to use it. It gets the job done, but it's an ugly bloated monstrosity. Not bad, just ugly.

The book Concepts, Techniques and Models of Computer Programming talks about designing a Multi-Paradigm (i.e. different Computation Models) language named Mozart/Oz where the different Concepts/Features are somewhat orthogonal to each other but still exist within a overall comprehensive system. You use what best fits the Problem Domain.

Unfortunately Mozart/Oz has not taken off in the Industry but C++ has fulfilled the niche though not as cleanly as envisioned in that book. Paradoxically, the breadth of the language features has become its strength. You can do Imperative/Object-Oriented/Generic/Functional/Concurrent programming all within the same language and using the same toolchains. Moreover, all these higher-level concepts do not prevent you from getting close to the metal if needed. AFAIK, no other "industrial" language even comes close. Alexander Stepanov, the inventor of STL is on record stating that he could realize his vision of a comprehensive, generic, flexible, efficient Algorithms library only in C++ (his attempts using Ada and Scheme both failed). That should tell you something about the power of the language.

Recent sibling comment has added to the overwhelming tone of HN comments on TFA - that C++ is a poor language.

Has Ken Thompson ever retracted those comments? I can't find anything to suggest he had a different assessment. The phrasing used in that interview / book sounds like this is a subject he has deeply considered and well-reasoned - certainly not an off-the-cuff 'C++ is awful'.

Ken and Bjarne may have some history, as you say - I do not know - but suggesting that implicitly reduces the legitimacy of his assessment may presuppose an inability to maintain impartiality on technical merits. I note that in the comments I quoted, and in other comments he's made about C++, his arguments are foremost about the quality and features of the language, with some hints about why it got to be the way.

Whether it's an appeal to authority, or a deference to someone with unarguable expertise, is perhaps a subtle distinction.

Moreover, basically anyone who has been programming in C++ for more than a decade would have an opinion similar to Thompson, even without knowing the history of the language. Most programmers I know have chose a subset of the language with some features they feel the most reasonable/useful for them. C++ has so many features that taking over another codebase might actually feel like learning a new language. It is an actual problem, because in order to be efficient in a language you need to actively use it by writing code, and it's hardly possible to actively train in all aspects of C++ on a daily basis.
Anyone who has been programming in C++ for more than a decade, knows pretty well how ISO works and how little influence Bjarne has on it.

Additionally, anyone who has been programming for more than a decade, is most likely a polyglot developer has is well aware of similar problems in other languages.

Which C#, TypeScript, Java, Haskell, OCaml, F#, PHP, Python,... subset do you happen to program on?

> C++ has so many features that taking over another codebase might actually feel like learning a new language. It is an actual problem,

No; People keep repeating this as if it were a truism, but it is not borne out by any empirical evidence. Sure there is some learning ramp to understand a new style of programming but it is far more easier than trying to learn and express oneself fluently in a whole another language. This has been true both in my own experience and most of the people/teams i have worked with.

See also the comment from "FpUser" in this thread echoing the same sentiments.

The link from where you took the quote lists another by Ken Thompson which hints at the history between Stroustrup and him.

People are people when it comes to biases, ego and personal relations whatever other characteristics they might be eminent in; so no need to deify anybody. History is full of great people who were mean/petty/egoistic towards perceived "competitors", eg; Newton and Leibniz, Edison and Tesla, James Watson and Racism etc. etc.

>Recent sibling comment has added to the overwhelming tone of HN comments on TFA - that C++ is a poor language

Your original posting of the quote added nothing to the OP article which is a quite nice introduction to Modern C++ features but hijacked the entire thread and set the negative tone for everything else with the result that instead of being a constructive thread on how best to introduce Modern C++ we are engaged in pointless arguments on the features of a language which has already been highly successful in the "Industry".

I am a practical man and language for me is just a tool. I do not dwell on C++ being too complex (which it is when you take it as a whole). All I care is - does it have enough features that I can be effective in creating application. C++ definitely fits the criteria for me. I've heard horror stories where each member of a team uses it's own subset but practically for many years of dealing with C++ I do not feel I ever had problems when I had to work with other programmers.

Programming general use libraries - sure. It is often enough hard to read black magic but I'll let people that are actually doing it worry about the problem. It does not have to propagate to application level programming.

> I've heard horror stories where each member of a team uses it's own subset but practically for many years of dealing with C++ I do not feel I ever had problems when I had to work with other programmers.

I feel the technical lead should be catching these problems during code reviews, and establishing best practices, etc. Also this problem exists in other languages, perhaps elevated slightly in C++, but until rust came along it was 1 of 2 choices you had for certain problems (C being the other obvs.). Speaking of rust I thing the jury is still out on whether it can catch up with C++ in terms of popularity.

“There are only two kinds of languages: the ones people complain about and the ones nobody uses.”
It may be hard to believe, but for much of the time of C++’s original development, it did not have a string class. Writing such a class was somewhat of a rite of passage, and everyone made their own. The reason behind this was partially the prolonged attempt to make a class that was everything for everyone.
The qsort() performance example in the beginning is a bit misleading. If you give the C compiler enough information (for instance an inline-able implementation of qsort()) then the compiler will happily "disolve" the comparison callback and custom types into a specialized "stamped out" version of qsort, just like std::qsort(). No fancy template magic needed for that, just an optimizing compiler.

The only difference between the two is that the C++ qsort implementation lives as inline code in a header file, while C's qsort lives "out of reach" in the C runtime library. If C's qsort implementation is in the same compilation unit (or LTO is used), a C compiler has the same optimization opportunities as C++.

For example here's a C qsort example where the compiler can see the qsort implementation (using an inline copy of MUSL's qsort). Note in the assembly window how the comparison callbacks have disappeared completely, this is basically C's version of "zero cost abstractions" (which really is just a fancy name for "compiler optimization passes", which isn't unique to C++):

https://www.godbolt.org/z/Mn4PfE9q7

First of all, qsort in C is not in-lineable and not even visible with LTO since it tends to be implemented in the C library while std::sort is always visible. Yes you can bring your own qsort, but that misses the point - you could just manually inline the comparison function at that point.

Secondly. std::sort is a template with the type of the comparator being a template parameter. This means that if you use a lambda or functor as the comparator, the template will create a std::sort instance that always calls that comparater and the decision to inline the comparator is relatively simple. In controst, for the qsort example the compiler will need to either inline the whole qsort at the call site (which happens in your example) or create a specialized copy of the qsort function for your comparator. If you switch the compiler to GCC neither happens in this case (it does specialize it for some of the other parameters, but not the comparison function).

From the intro: "2018 is an exciting time to be a programmer, with so many good “full service” programming languages to choose from: C, C++ 2017, Go, Python, Rust and who knows Swift too.". What does the author means by "full service" here?