top | item 20567158

C++20 Is Feature Complete; Here’s What Changes Are Coming

78 points| jandeboevrie | 6 years ago |hackaday.com | reply

64 comments

order
[+] ncmncm|6 years ago|reply
This article might seem confusing.

That's because it is. There is hardly a paragraph in it that is wholly correct, where they actually mean anything.

C++ itself is much easier to understand than the article.

The real purpose for all the constexpr-related apparatus, as well as much of Concepts, is to make it much rarer that anybody needs to do "template metaprogramming". Instead of writing Template Metaprograms to run at compile time (a very strange functional pattern-matching language practically nothing like C++) you can usually write ordinary C++ code.

Coroutines are a new flow control primitive showing up in lots of languages lately. The C++ version is the same as the others.

The main benefit you will see from Concepts is overwhelmingly better error messages when you misuse a library component, whether Standard or your own.

Modules is a big step toward enabling a modern build infrastructure, as already seen in lots of newer languages that got benefit of hindsight.

All the old stuff is still there, because billions of lines of old code still use it. You don't have to use it in new code, but it all still works.

The biggest difference between old and new C++ code is that good new code uses value types more, and reference types less, making everything safer.

Coding modern C++ is overwhelmingly more fun than coding C++98 was, but it is just as fast as ever, and better than ever for writing fast, powerful, nice-to-use, no-compromise libraries.

[+] hackandtrip|6 years ago|reply
I got had to fight with template metaprogramming lately, and I can't be happier than reading about this. Do you have any sources when one can learn in a non-confusing way about this new stuff, especially Concepts?
[+] gigatexal|6 years ago|reply
I’m not a C++ dev. I took one class of it in college and even then it was 90% C and only hit pointers and classes on the final unit.

But holy smokes this is not your grandmother’s C++, is it just me or is the language trying to be all things to all people? It’s getting too big, no? I mean how long do you have to be writing C++ code to fully master the language? Or can you be a high level dev without ever touching the new features? I’m assuming production codebases are likely still stuck on older versions of the language and might never move on.

I hope golang doesn’t grow this large over time.

[+] alexhutcheson|6 years ago|reply
Yes, it's very complex and hard to stay on top of current best practices.

However, every one of the major features listed in this post replace an existing language feature with something that is easier/safer/less verbose. For new code you shouldn't have to use the old features, and you can just rely on the new ones. Existing code is trickier, which is already a problem for large C++ codebases. You'll find dramatically different styles depending on when the code was written.

All in all, though, the recent changes have made C++ much more pleasant to program in. They're mostly less complex for an application developer than the things they are replacing, and the really complex bits (concepts, etc.) are only needed for writing complicated template libraries.

[+] gumby|6 years ago|reply
> is it just me or is the language trying to be all things to all people?

Well yes, in the sense that it's a systems programming language designed not to be a single-paradigm language (you can write procedural, or somewhat functional, or classic OOP, or generic functions-based OOP) and to be very efficient at all.

Some of the features are seemingly arcane in order to preserve the zero-cost abstraction approach as much as possible.

> Or can you be a high level dev without ever touching the new features?

So some features are arcane as I wrote above but some are deliberately high level, designed to make it easier to write safe, efficient high-level code without getting into the weeds. Being able to type

    for (auto& a_frob : from_manager) ...
and have it be fast, efficient and not leak memory is a feature, right?

> I hope golang doesn’t grow this large over time.

Go's explicit design goals are the opposite: have only a few constructs, a specific "opinion" as to how things should be done, and to deliberately limit expressiveness in favor of other objectives. So I doubt it will come close.

Edit: I don't agree with go's design criteria, but I respect them.

[+] asauce|6 years ago|reply
One of the worst interview questions I have had was "Rate your C++ knowledge from 1 - 10".

I had just finished my second year of college, and although I felt fairly confident in my C++ abilities I had no idea how to answer. I thought it would be best to be honest and said "4" based on the subset of the huge language I knew (honestly this rating was probably too high at the time!).

One of the interviewers was obviously unhappy with the answer, and was unpleasant the rest of the interview. I have always wondered what they expected from such an vague question.

[+] sp332|6 years ago|reply
Oh yeah, C++ has been huge for decades. You pick a subset and program in that. The changes in C++11 had structural implications that took years to work through which is why it was late. The working name was C++0x because they expected to release it in '08 or maybe '09. http://www.stroustrup.com/C++11FAQ.html
[+] saagarjha|6 years ago|reply
> I mean how long do you have to be writing C++ code to fully master the language?

To be honest I don’t think you can ever fully master the language.

[+] tejohnso|6 years ago|reply
I recently started trying to learn c++ and I'd say I've got the basics down.

Sometimes I'll watch a talk by Scott Meyers or Jason Turner and realize how little I know, and how deeply complicated things can get. Then I go back to my code base and continue being productive writing useful code. I know it's probably not perfect, but it's still satisfying.

As for reaching perfection or mastery, that's an enjoyable journey, even knowing that the final destination is likely unreachable.

[+] agumonkey|6 years ago|reply
I don't write cpp but it seemed c++11 and later were almost shrinking.
[+] hawski|6 years ago|reply
I am C++ developer by career and I am pretty much bashing the language all the time. To preserve my sanity I like to use C in after-hours. However looking up C++20 and the direction whole language is going I see there are things I would really like to see in C, while preserving C simplicity. Standardized attributes like [[fallthrough]] and others for functions seem nice. Anonymous functions are nice. They look a bit ugly, but function pointers already look even worse. It would not hurt to have modules and consteval functions in C, but then one still needs templates to really ditch the preprocessor and that's a tough one to solve.

Having said all that C++ is really in a need of a clean cut between legacy features and the blessed way. Backwards compatibility is a noble cause, but there is also the whole weight it pulls around. Maybe something like [[deprecated]] attribute could be extended to handle more cases. Maybe C++ needs it's own "unsafe" block, something like

  [[unsafe]] {
    *((void*)0) = 0xDEAD;
  }
Essentially having an ability to clearly mark all those different styles of different versions of C++ really. So that compiler could help you to control it and in case of a green field project totally guide you to use only the most modern idioms with an escape hatch. Of course the problem is that to help with the complexity more complexity would have to be added.

I am a bit on the crossroads. From one side I start to see, that there is some hope for C++. But on the other I feel like running away, especially since I'm looking for a job. In no particular order: C, Rust, Java, Kotlin, Scheme, Julia, Go, OCaml, Free Pascal, Swift, TypeScript, Lua/Terra, Zig.

I had a funny thing with C++. One project I worked on was used in the debug version all the time, to be able to drop to debugger when needed. At that point I started to wonder why not just use Java already, instead of trying to do a manual Java and fail at it.

[+] empyrical|6 years ago|reply
Despite the slight differences they have from the C99 version of them, I'm pretty happy to see designated initializers in C++20
[+] ilaksh|6 years ago|reply
Sounds amazing. Anyone have code examples that integrate a lot of the newer stuff?

Dumb question. Why isn't omitting 'return' always an error in gcc rather than just a warning?

[+] ahartmetz|6 years ago|reply
In any case, just add -Werror=return-type to your compiler flags... After I had forgotten a return once, that option saved me several times.
[+] plorkyeran|6 years ago|reply
int foo() { bar(); } is a perfectly well-formed function as long as bar() never returns. Allowing this without requiring bar() to be annotated as noreturn is generally considered a mistake, but correcting it would break existing valid programs.
[+] Gibbon1|6 years ago|reply
Likely answer is, doesn't really cause problems for anyone in practice. Experienced C++ programmers fix warnings.

Also the ABI specifies how to call and get the return value of a function. The long and the short if it is the execution thread doesn't go off the rails if there is a mismatch in expected behavior. Your data may be garbage tho.

[+] Ididntdothis|6 years ago|reply
Looks pretty good. But I don’t understand why they don’t do string interpolation like C# and others do.

“I= {I}”

Is much better and less error prone than

“I= {}”, I

Or am I missing something?

[+] _hardwaregeek|6 years ago|reply
Probably some syntactical reason. If you allow arbitrary expressions inside string interpolation, you'd need to have some form of state in your lexer to figure out when to lex the characters into tokens or just keep them as raw characters. It's not so easy as looking for another brace, as you can have expressions that have braces (lambdas). Plus, string interpolation can then be nested, which you may not want.
[+] plorkyeran|6 years ago|reply
The format library is a pre-existing library which is being standardized. String interpolation cannot be implemented in a library, and requires language extensions. Perhaps they should have done that instead, but that's a significantly more complicated task than merely adopting something that's already well tested and proven (and even that was far from trivial).
[+] bsder|6 years ago|reply
C++ (and C) have a fairly odd characteristic in that it is really hard to definitively figure out what is an identifier.

It's one of the reasons C++ takes so long to compile.

It's why the "modern" languages all seem to be converging on having an explicit token that signals "This thing is an identifier : this thing is a declaration".

[+] royjacobs|6 years ago|reply
I don't think you'd be able to evaluate your expression without some kind of runtime reflection. Specifically, how is a standard library method supposed to interpolate {l}? It doesn't have any information about which variables are present in some kind of format string.
[+] lousken|6 years ago|reply
I've had C++98 at school, but how would I learn C++17? Scott Meyers wrote C++14 but he retired from C++ development so what are the best alternatives?
[+] antisemiotic|6 years ago|reply
Changes from c++14 to c++17 are nowhere near as dramatic as c++98 to c++11, so you can go with Scott Meyers and fill in the gaps from cppreference.com, for example.