And is there big difference between the latest version and C++ from 5 or 15 years ago?
How do you guys keep up when a huge language is continually changing?
And is there big difference between the latest version and C++ from 5 or 15 years ago?
How do you guys keep up when a huge language is continually changing?
As compared to 15 years ago, the language is almost unrecognizable. As compared to 5 years ago, it's a bit more convenient to use, but not wildly different. C++ is a relatively old language, but it didn't have an real standard until 1998, and even that version was more about documenting what was out there rather than prescriptively designing anything. Before that (and to a lesser extent since, cough-cough-Microsoft-cough), it was a mess of incompatible OS features, compiler-specific semantics, and inconsistent tooling. In the right environment, it could be the most amazing and productive language, but it was a very short trip from "this is great" to "here be dragons and assorted hellbeasts".
C++11 has been by far the biggest change. Beyond the huge impacts on the language itself, it was the beginning of the current standards cadence of new standards every 3 years. To point to a single feature, C++11 introduced smart pointers and move semantics, which are the only "modern C++" features that I use in almost every single source file.
>How do you guys keep up when a huge language is continually changing?
A new version every 3 years is not that fast, really. And the new features are totally opt-in and backwards compatible; code written decades ago will, for the most part, still compile today. That means that you can slowly adopt new features one at a time as they make sense.
>why a low level language is going through so many new versions?
First, C++ isn't really a low-level language - or at least, it doesn't have to be. It hits a really interesting sweet spot where you can express powerful things concisely, and yet predict more or less exactly how things will execute if you think it through. It doesn't run on a VM like Javascript or Python, and it doesn't have the esoteric abstractness of Haskell, but it's certainly much higher-level than C, and there are a number of layers farther down than that.
Second, the reason for the iteration mostly has to do with filling in features that everyone had to build for themselves, and which were often platform-specific. Each version has progressively expanded the standard library with things like cross-platform concurrency primitives (std::mutex, std::thread), file I/O (<filesystem>), efficient string manipulation (std::string_view), and improved templated containers (std::optional, std::variant). Adding smart pointers in C++11 was about moving best practices about memory management into the language. Adding file I/O in C++17 was about standardizing cross-OS compatibility layers. Adding modules in C++20 is about improving standard buildchains and package management. Prior to C++11, every organization had to have their own implementations of all of those things, which required a massive investment into internal "standard" libraries, styleguides, and tooling, which were totally incompatible with each other. In the modern C++ era, a lot of those things can be the same for everybody, which makes everything more efficient - easier to transfer to a new codebase, easier to start from scratch, easier to share tools and libraries.
That was the original intent, I think, but decision to incorporate the STL caused the standard library to change massively late in the standardization process.
P.J. Plauger wrote a book on the 1995 version of the C++ library, that ended up being massively different than what the standard adopted: https://www.amazon.com/Draft-Standard-Library-P-Plauger/dp/0...
Coming from Turbo Pascal 6.0, it provided me a world with access to C based tools, without having to endure typical C unsafe code.
And yes, there is a big difference between C++ 03 and C++17 and an even bigger difference from C++20 but C++ has done a good job of maintaining backwards compatibility so almost all C++98 code will still compile with a C++20 compiler.
How does anyone keep up with the changes in technology over the last 20 years? At least with C++ much of your old knowledge remains relevant, more so than a Visual Basic programmer who is now using JavaScript with the latest UI framework flavor of the month.
I'm just happy I actually make/simulate things for a living than worrying about learning new tools I didn't ask anyone for.
C++ aims to be the high level language which leaves no room for another high level language to be even more optimized below it - “pay for what you use”.
Having its roots in C, while having high level abstractions, C++ also has a lot of low level functionality which is hard to use correctly and safely unless you have a lot of experience (e.g. raw pointers). This low level functionality is sometimes needed, but definitely not always, and the recent iterations of the language over the last decade try to both add new abstractions which make the language easier to use, and deprecate the most tricky parts which are not really needed anymore and which have better, modern alternatives (this being limited by the need to maintain sane backwards compatibility) - all the while maintaining C++’s design goal described above.
An example of an addition is unique_ptr and shared_ptr added in C++11 and which make managing ownership and correct lifetime of allocated objects much easier.
An example of a deprecation is eliminating gotcha uses of the ‘volatile’ keyword, and thus simplify the language. (I believe this one is still undergoing approval.)
There is a big difference between modern and “classic” C++, but it’s mostly a good difference - C++ is much easier to start using and to teach than it was 15 years. It still has a way to go, and the standardization committee makes a lot of effort in that direction.
As for keeping up - it’s definitely a lot of work. Learning C++ isn’t something you start and finish - it’s more like culture. You spend some part of your life studying and enjoying it, and there’s always something new.
We can hope for a future in which learning C++ is something you just start and finish, but we’re not there yet (if ever). I’m not sure if that’s a good or a bad thing :)
Chip designer: In a high-level language like C++...
- auto var = eval()
- add_observer([this](int value) { this->log(value); }); // lambda expression
- vec2 = std::move(vec1); // everything in C++ by default is value-type, so this saves a copy
- for (auto&& [k, v] : treemap)
- auto ref_ptr = std::make_shared<SomeValue>(42); // ref counting
- auto unique_ptr = std::make_unique<SomeValue>(42); // non-sharing, uniquely owning ptr. can only be moved
- module foo; import "some-header.h"; export something_from_header; export void your_own_func();
In reality these are 90% features you need to migrate from C++98 to latest version. Don't be terrified by thousands pages of paper, just use them as a reference when you need to.
To answer your question, one of the motivations behind the (ongoing) design of C++ is to factor out and codify common C/C++ coding idioms. Almost every feature, library or language, can be traced back to this motive. So most "new" features are less so "new" and more so "that thing you're doing informally? It's formalized now." E.g. concepts codify how template parameter requirements have traditionally been stated.
C++ and C have both been around for ages. When they first arrived, most (all?) computers were single threaded and therefore neither of them put threading utilities in the standard library and in updates to both languages, now C and C++ both have libraries for dealing with multiple threads (and I believe an improved memory model that takes threading into account.)
Almost all programming languages evolve over time. Programming changes, computers change, and people gain experience and figure out what the pain points are in a given language. Naturally, we take what we learn and apply it to future language versions.
Every major language evolves over time. Java 8, ES5 Javascript, Python 3 were all pretty major iterations of each language. Similarly, C++11 went as far as Java 8 in the number of things that it got up to "modern" standards of convenience and power. The goal seems to be towards offering some of the conveniences of heavier or more high-level languages, but with the power of a low-level language.
> And is there big difference between the latest version and C++ from 5 or 15 years ago?
From 5 years ago, probably not. 15 years ago, C++98 was likely to be the flavor of C++ being used. C++11 was still in early draft mode, and was called C++0x. Today, C++ can look like a dynamically typed language, e.g. using "auto" type inference for variables, lambdas, and range based loops. If you follow something like the Google C++ Style Guide, you'll never see a raw pointer (C++11 introduces reference counted smart-pointers).
> How do you guys keep up when a huge language is continually changing?
Major language iterations are generally pretty uncommon. Beyond that, following a good style guide that is maintained by other people.
But as with anything C++, you and your team need to decide on a per-project basis on how far down the rabbit hole you are willing to go. There is a world of difference between C with classes and metaprogramming parser generators. And to the standards credit, a lot of the new stuff can be used individually.
Its getting modern, but its no where near perfectly. There are three different ways to allocate heap data and at least one dates back to the 70s. There are at least five ways to initialize a variable last I checked. The language is ludicrously complex to parse for both a human and a computer because its been iterated on for so long.
Because the design space C++ occupies is so complex and lacking almost any feature of it kills competition Rust is about the only real competitor in the space of "modern language that does absolutely everything" besides peers like OCaml that often have too arcane a syntax for the C family linguists to get in to. But compared to C++, Rust is way more cohesive just because it started one decade ago rather than four and has much less baggage so far. And with its editions system will likely never have permanent unmitigated baggage to its benefit.
I've found code where developers casted perfectly useful data structures to void* for no reason to then index into it by memory offset to access its fields, I've seen well architected concurrent classes destroyed by consumers "friending" it and then directly addressing internal private data meant to be guarded via accessor functions, and more.
C++ gives you infinite ways to shoot yourself in the foot, and even if you are the savant genius god programmer who manages to navigate its neck deep swamp of complexity your coworkers or even worse random strangers you collaborate with on the Internet absolutely won't.
C++14 and 17 mostly just add some library features and clean up rough edges. You'll know you know C++11 well when you start wanting those features.
Only then look at C++20. Bonus: there might actually be compiler support for it by then. (Caveat: You might want to learn modules sooner; they will probably be the most visible day-to-day change.)
If you can, I would learn Rust instead. Rust is a much smaller language that purposely limits the way you use the language to encourage particularly safe practices, and tends to favor designs that are hierarchical instead of allowing hairball object graphs. Rust also guides you at the compiler level in ways that C++ programmers must learn to do by heart, or simply leak memory and create nasty patterns in their code.