Hacker News new | comments | show | ask | jobs | submit login
C++17 is formally approved (herbsutter.com)
253 points by ingve 96 days ago | hide | past | web | favorite | 132 comments



C++ shows that in theory you can fix any flaw in an existing programming language as long as you maintain backwards compatibility by simply adding more features. The only thing you cannot change are implicit defaults (e.g. pass by value is the default, you have to manually opt out to pointers or references).

I like modern C++ because for me it's a reasonable compromise between java safety and C safety. Other than out of bounds memory accesses and legacy code I feel there is not much that can go wrong. However compiling C++ projects takes ages and in the projects I've worked on I often have to modify headers that are included almost everywhere. Every trivial changes requires a 5 minute rebuild.

After working with several high level programming languages with slow compilers I realised the following: typing is fast, compiling is slow. There is a reason why go is so popular. It offers that tradeoff in fast turn around time / compilation time with reasonably good performance and simplicity in exchange for more keyboard bashing and keyboard bashing is a cheap price to pay for what you're getting back.


> C++ shows that in theory you can fix any flaw in an existing programming language as long as you maintain backwards compatibility by simply adding more features.

I feel like C++ proves exactly that you can't.


> I feel like C++ proves exactly that you can't.

Depends on what you mean. At a minimum, I think it's clear that C++ has avoided a Python 2/3 style split in the community. This means that otherwise relatively conservative users (I'm thinking of users on supercomputers in this case) are upgrading quickly to new C++ compilers and standard versions.

On the other hand, C++ has always been a kitchen sink sort of language, and it is even more so now. As codes age, they tend to grow and not shrink in the feature set they use, and so long-lived codes will probably never completely escape the demons of previous versions, regardless of how nice the shiny new features are.


Lol. At my work I am still eagerly awaiting the arrival of C++11.


That's not the point. The point is that, when you get it, you won't encounter a list of breaking changes and your code will continue to work.


>you won't encounter a list of breaking changes and your code will continue to work.

Sure, that's why my gstreamermm app refused to build when I switched to --std=c++17


Here's the list: https://stackoverflow.com/questions/6399615/what-breaking-ch...

Was it one of those? If not then the fault was with your code or the implementation, not the spec. The language itself is very good at maintaining backward compatibility.


>you won't encounter a list of breaking changes

>list of breaking changes

Yeap, some shit with smart pointers in glibmm, didn't investigated much.

https://bugzilla.redhat.com/show_bug.cgi?id=1438766


>C++17 will remove support for old-style exception specifications

Right, you've been told for some time that those were deprecated. At some point deprecated features go away.


If C++ is so bad then why:

1) are 90% every really large software projects written in C++. All the programs "everybody knows" just happen to be in C++. Examples include Chrome, Windows, Microsoft Office, Adobe tools, KDE, Autodesk, ...

Clearly those programs have massive scopes, large complexity, the need for extensive abstractions, the need for large teams cooperating, tests, ... all the stuff we value as programmers.

2) Are all programs in most other languages so ... small. In scope, in features, in ... Just look at Go programs on github. Or python ones.

Very large Python projects are a few 10's of thousands of lines of code. And they are limited by their complexity. Somehow C++ programs seem to have less of this problem.

Very large javascript projects don't even seem to get above a few thousand lines of code. And reading them, I can see why. Typescript at least seems to match Python in how much complexity it can contain without imposing too much of a burden, but that language doesn't match C++ either.

Most of those fancy languages are artificially limited in some ways. For instance, you cannot easily link QT into Go (nor can you do that with many other libraries, GTK has the same problem). C++ does not have that problem, and if it does, you can solve it. I do not claim doing so is easy, but it can be done. You're not stuck. Go on IOS ? It sort of works, with a boatload of limitations that make it utterly unworkable. C++ on IOS ? It works, with less limitations than Objective C.

I feel like C++ gets a much worse reputation than it deserves. Much worse. It is not the solution to everything, of course.


1) I know so many programs which are the same size or bigger than your "well-known" programs you probably never heard of but still use daily - They are just not desktop programs, a place where C++, for various reasons, is often the language of choice, but desktop programs are (for better or worse) just a small subset of all programs written.

2) See answer above.

> I feel like C++ gets a much worse reputation than it deserves. Much worse. It is not the solution to everything, of course.

In the end it all boils down to Stroustrups quote about programming languages: 'There are only two kinds of languages: the ones people complain about and the ones nobody uses'


Point 1 is mostly down to history I suspect. The big Adobe stuff is in C++ because they started writing them when C++ was The Thing. Probably quite cutting-edge then (not that it doesn't have some cutting-edge features now of course, that's what makes C++17 and C++20 and so on worth watching). Windows, Office likewise, although I've always assumed that an increasing chunk of Office is now written in C#. I have no evidence of that by the way. KDE - again of its time. Autodesk, likewise.

And then that gives you a huge historical inertia. Chrome started out using KDE's rendering engine, which was written in C++, at a time when writing cross-platform GUIs wasn't really feasible in anything else if you wanted it to also be reasonably fast.

And they stay in C++ because changing languages is a right pain in the whatsit, and C++'s ABI is so variable across platforms and compiler versions through history that integrating components in other languages is often not worth the effort to maintain. Not that it hasn't been done, of course, and done well. Look at how Firefox are now integrating Rust components in their C++ codebase - although they're doing it by relying on Rust's ability to expose a perfect C ABI, and C++'s ability to call it.

Point 2... yeah. I get this. C++ has a higher complexity bound than many languages, especially dynamic ones. C++ used as C++ rather than C-with-classes has a strong type checker and some very robust capabilities around memory management, program integrity, metaprogramming (even though the syntax is dire and the compile times are horrible). C++ expertise in large software construction is widely available. C++ will compile down to efficient machine code that runs well on many platforms. These are all huge advantages in large projects.

Python has its troubles with concurrency, and the lack of type information in the source code to help maintainers. Go is just too young - I suspect we're going to see some really giant Go projects emerging over the next ten years, especially outside the space you can see on GitHub. There will be big enterprises deploying enormous Go codebases, although they'll likely be made up of multiple components instead of one giant thing like we used to do. Rust's too young, Haskell's got the chops but is too weird for most people (and its own problems, although Stack has really helped with the developer experience), JavaScript is entirely unsuitable to a large maintainable codebase. I'd guess TypeScript can probably go a bit further then Python in that space, at least until Python's new type annotations start getting fully checked by tooling at which point it returns to parity (or exceeds it, due to not being JavaScript in disguise. Guess what, I don't like JavaScript, who'd've thought!)

But still we've got C++'s inertia to thank for a lot of this. It's huge, it's old, it's still being developed and still being used and there's a lot of knowledge and a lot of capability out there.

But then look at newer disciplines. Look at mobile apps - yes you can write C++, but the native languages of Android are Java and Kotlin, and of iOS are Objective-C and Swift. What are new developers going to want to do - learn Kotlin and Swift or figure out how to shim C++ into those platforms via the variously awkward methods available?

What about the web? How many web applications are written in C++? Very few, I suspect. It's all C#, Java, PHP, Node, Python and other modern things which may or may not be considered sexy.

C++ dominates in the older disciplines, the older software that's still here and we still use and will use for a very long time.

I think elsewhere it's being passed by, especially as we get languages like Rust and Go which are considered as possible replacements in the "I really need this to go as fast as possible" camp.

It's a shame really, as C++ is still a powerful, impressive language and the new stuff is fantastic. But I always felt when I was working as a C++ developer that I wished I could turn off those C-compatible core behaviours and completely block those implicit-but-dangerous type conversions, and get the compiler to scream at me about dangerous pointer usage (I believe something along those lines is in the works for a future standard).

And also a shame about D, which has its followers but has been largely ignored, overshadowed by C++ to start with and later passed by the new languages which get all the hype.


It definitely can't solve the problem that the language is hard to understand:

https://www.google.co.uk/amp/s/akrzemi1.wordpress.com/2013/1...


C++ is a tool for low level systems programming. Why would you compare that with GO? Also, I would argue that C++ is _WAY_ more popular than GO. It allows you to be productive in the real world, utilizing legacy code, legacy libraries, APIs, etc. Very few projects are 100% greenfield.


Many desktop apps are still written in C++.


"Many" is an understatement here. Pretty much every Windows desktop app is written in C++ and Windows runs on over 90% of all desktops.

Adobe will never rewrite Photoshop in Rust or whatever. If you thought burying COBOL was hard.. C++ will outlast humanity.

I can already hear the Alien scientists: "An amazingly intricate and convoluted language for such a primitive species. The mismatch between their mental abilities and their language might explain the bug which caused the incident.."


As someone that has spent quite some years writing Windows software, actually since the .NET introduction and the maintenance status of MFC, the majority of Windows desktop apps are written in a mix of .NET and C++.


> Pretty much every Windows desktop app is written in C++ and Windows runs on over 90% of all desktops.

I think you may be the one overstating things. Where I work, a biomedical device firm, for every one app written in C++ there is either one python or matlab prototype of it and 5 python/matlab apps to test it/show it off. I'm sure for other places that number is far higher. I honestly don't see how you could quickly prototype sufficiently complex ideas any other way.

Better said, I can build a working Kalman filter, load saved patient data to it, create a primitive db, save output data to said primitive db, build a primitive, but functional enough that non-technical people can use it, GUI, from scratch, to plot said output data in Python all in a couple hours. Can you do that with C++ for the same time frame? Heck can you do it within an order of magnitude of the time I used? If you can't, why should you be spending an order of magnitude more money for it?


You wouldn't have to rewrite Adobe. You could rewrite one component of it (0 cost FFI). That's fair more reasonable. I think Servo is proving that Rust has a lot of potential for slowly replacing a C++ codebase, piece by piece.


On Windows, Rust still has the problem that it needs to be as easy as C++ for working with COM, specially now with UWP.


Is anybody using C++ with UWP? I would have thought the obvious choice was C#.


Yes, via C++/CX and when C++/WinRT gets ready by the end of the year, it will eventually replace C++/CX.

Also note that Blend has first class support for C++/CX projects.

https://moderncpp.com/2017/08/25/cppwinrt-2017/

Of course most developers using C++ with UWP is Microsoft itself, for stuff like XAML engine and the new Visual UI composition engine, and game devs.

XAML is also the official replacement for MFC.

As I mentioned in some other thread today, there is hardly any pure C++ application nowadays on Windows, they are mostly a mix of .NET and C++.


Sure, people will ultimately use the tool they think is right for the job, given the people they've hired, etc. C++'s strength isn't UI programming (might be generalized to things that require more input from designer's than programmers), but writing high-performance, low-abstraction code (which could very well be the dominant factor in the success of the desktop app, hence the choice).


>C++ shows that in theory you can fix any flaw in an existing programming language as long as you maintain backwards compatibility by simply adding more features.

Well, "adding more features" can't be done "simply" if you want to "maintain backwards compatibility"; indeed, in the process of doing this is that the "flaws" are potentially augmented.


They also have removed features that were deprecated in C++11 and C++14.


Yes! These are underrated items on the change list. Establishing precedents and habits for removing harmful things (like trigraphs) is very important to the future of the language.


There's some funny ones there. std::random_shuffle because it relies on rand() which may be bad, but ironically most (all?) the rng's that are in the standard library would be considered "bad" by modern standards.


"bad" for what purpose? The linear congruent stuff and Mersenne twisters, for example, are leaps and bounds better than a typical rand() implementation, and very appropriate for many uses.


Sure, but we have generators now that are both faster and better, so there's no point in using the standard ones, aside for convenience.


    aside for convenience.
You say that as if it is a small thing. Convenience, lack of additional code to maintain, consistency across platforms - for many projects these things will easily trump any algorithmic improvements from using something else.


> keyboard bashing is a cheap price to pay for what you're getting back

Only if your program is trivial. That is, if you can afford to run it over and over with results you can verify in the output as being incorrect, sure, keyboard bashing works.

Most of us work on programs that have been made trivial by abstracting the complexity into a framework or protocol library - like a web server. You can keyboard bash out a correct rest implementation on top of a routing library in minutes.

The problem domain is tiny(but really flexible!), and largely automated by code generation in most languages. The programmer is only there to cross some t's and dot some i's.

It would be a waste of productivity to write your own http server from the ground up. Writing one is non -trivial. For every new programming language that wants to serve web apps, a webserver must be written in that language. Having a compiler that verifies or does more for you on a non-trivial program is great. Not saying c++ is the right language here, just that a statically compiled program with an expressive type system catches more errors at compile time. Some/(most) bugs are unapparent in localized, repeated runs and unit tests that really only ever test a small subset of the range of possible inputs.

I like easy as much as the next programmer, I just mourn the fact that we can't seem to provide a safe, simple and easy in the same programming language.


Other than out of bounds memory accesses and legacy code I feel there is not much that can go wrong.

If only we could stop at single-threaded applications :-)

I'm not convinced modern C++ stops all issues with pointers/iterators and ownership either. But it's hard to tell because every large-enough application inevitable has to interface with legacy pointer code.


The point about legacy pointer code is valid, but the benefit of the newer pointer / iterator / ownership stuff isn't really that it is in and of itself a magic bullet.

What it does do is make it easy to reason about how pointers are used across the application. Also worth noting that even with legacy libraries, you can wrap a given pointer with std::unique_ptr or std::shared_ptr and provide a custom deleter and maintain reasonable safety guarantees.


I do get it's easier. I use std::unique_ptr when interfacing with legacy code because I like that I need an explicit .release() to relinquish ownership. It's self-documenting.

But I was considering modern C++ compared to, for example Rust. I'm not sure if the memory safety issue that Rust solves still exists as strongly with a purely modern C++ codebase...but then again I never run into those either.

For threads it's no contest between Rust and C++, although TSAN is pretty damn nice.


Pointers are great! Without pointers, the web would not exist!


Your complaint about the slow compilation times might be addressed partially by Modules, expected for C++20. VS 2015 Update 1 and Clang already have experimental support.


in my experience when testing the current modules implementation, PCHs are still a good deal faster; if you use CMake they are dead easy to set-up so you may as well use them today.


Modules help, but you're still trucked if you change an underlying header.


> I often have to modify headers that are included almost everywhere.

I think this problem started with templates - previously you wrote abstract base classes (interfaces) and concrete classes had most of the code changes. I avoided templates where possible largely because of this.


nit: Aren't pointer arguments also pass by value? The data is the memory address not the underlying pointed-to object.


You can use the SaferCPlusPlus library[1] to get closer to "java safety".

C++ compile times are a problem. Apparently there is a C++ interpreter[2]. Anyone have any experience with it?

[1] shameless plug: https://github.com/duneroadrunner/SaferCPlusPlus

[2] https://root.cern.ch/cling


Here's a good rundown of all the changes in C++17:

https://stackoverflow.com/questions/38060436/what-are-the-ne...



Done. Thanks!


Did modules/import not make the final revision? I was quite looking forward to that feature.


Nope, but they are in the pipe. Maybe we'll see them for C++20.


So I'd like to learn more about modern C++ and how to write it, but I'm not really sure where to begin. I've tried a couple of times, but coming from a C background, my code tends towards C styling with only the occasional use of C++ features.

Is anyone aware of a good tutorial or reference list for writing good modern C++ (C++11 or newer, I guess)?


The following is a readable and modern FAQ which describes most language features: https://isocpp.org/faq

My preferred reference for the language and standard library: http://en.cppreference.com/w/

The following is a longer guide on modern C++ style: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC...


As a newcomer to C++ myself, I found Stanley Lippman's C++ primer to be helpful. The latest edition includes the newer features.

And in case it helps, the main things I find myself using differently to C are:

- Smart pointers. If you're not using them, use them. They're amazing. Seriously. Never have to worry about freeing something ever again.

- Object oriented design.

- Const reference arguments.

- The occasional auto.


I'd second C++ Primer. It's a great overview of the language and has been updated for C++11. Unfortunately it was written too early for C++14 and beyond so if there is a newer edition planned (I've no idea) it might be worth the waiting. In any case C++11 was the big change for C++ so the fifth edition is still worth while.

One word of warning though, there's a confusing similarly titled book called "C++ Primer Plus" which you should avoid at all costs.


I'd add RAII to this list. Also, I find simple template functions to work as an incredibly powerful macro system.


I really enjoyed "Efficient Modern C++". I'd describe it as a good overview of new features in C++11 and 14, how to use them, and how they fit together, but I'm not sure whether it makes for a good "C++ for C programmers" book.


Check out this recent post by Simon Brand on this subject - https://blog.tartanllama.xyz/learning-cpp/


I really enjoyed "A Tour of C++" by Bjarne Stroustrup, which is a short book giving an overview of C++ features. It sticks to modern C++ practices from the very beginning.

Unfortunately, the book is C++11 only and correspondingly does not talk about C++14 or C++17.


It's very nice to hear progress on the C++ all the time. On the other hand, I cannot find any news on the C2x progress, as if C did not evolve.


So I used C++ a long time ago but moved to Java/dotnet/python platforms. I do miss some low level stuff but not random crashes.

Is there a reason to use C++ any more? Has anyone gone back and had good experience? I'd kinda like to but am wary of the old problems. (The other problem is that most interesting business logic is no longer in C++.)


C++11 changed the language significantly and for the better, and each subsequent version has taken it further in the right direction. You can now use C++ as a high-level tool without much or any concern for manual memory management, and can do a lot of functional-style programming very easily and nicely. C++17 in particular adds features that bring the syntax closer to modern high-level languages almost to the degree that it feels like a scripting language at times. Stuff like automatic destructuring, variable definitions scoped for all branches of conditionals, etc. It's really one of my favorite languages, though this year I'm not getting to use it as much.


I don't quite see how the "random crashes" were not a programmer error, unless you were using a terribly unstable/buggy library. If you want performance (in the real world, utilizing code you have, libraries you purchased/wrote, etc) C++ is the way to go. Java/dotnet/python are not comparable or interchangeable with C++. And like any tool you have to work within its limitations.


If the parent used C++ in the old days, using the "Better C" paradigm im sure he will have bad memories being plaged by manual resource management.

Its a whole new language and much more stable when you just use smart pointers, take care of ownership and know how to use the right reference types.


C++ still produces the fastest and most memory efficient programs.


Fastest compared to what? Everything? That is definitely not true.

If you were referring to Java/dotnet/python, well yeah. (I'm honestly curious to know what you meant).


Definitely not formally, pedantically true. But, we aren't defending a mathematical thesis here. We're having a casual discussion. Still... let's see: Given a generic workload with equal effort put into optimizations... Should you expect C++ to be faster?

Compared to PHP, Python, Ruby, C#, Java, JavaScript: true with some pedantic exceptions.

Compared to Haskell, oCaml: Usually true, unless facing both well-suited and well-tuned code.

Compared to small volumes of carefully crafted and profiled Fortran, C or Assembly: usually not true.

Compared to CUDA: Not true for applications well suited to GPUs. Still true for situations that map poorly to GPUs. Except CUDA is almost entirely C++! Recent CUDA compilers on recent GPUs handle C++ code directly very well. Nearly everything but exceptions and thread local storage is supported.


My point was that the statement "C++ still produces the fastest and most memory efficient programs." is basically meaningless without any context. There are a fair number of situations where other languages can beat C++ in either or both of those metrics.

"C++ can produce very fast and memory efficient programs." would have been fine -- or some variant that compared it to specific languages, such as you do above.

I don't think it's being pedantic at all to ask what the OP meant. It was a vague statement that (depending on what they meant) is either true or false.


Given an experienced programmer in all those languages that OP mentioned, I would expect the C++ version to perform faster. I didn't put much qualification because I don't think it needed it.

Remember that the original question was: ...moved to Java/dotnet/python platforms...Is there a reason to use C++ any more?


"remember that the original question was: ...moved to Java/dotnet/python platforms...Is there a reason to use C++ any more?"

^ Yeah, and I specifically addressed that possibility in my original response to you.

I was just trying to clarify whether you were referring to that comparison, or a comparison of C++ vs all other languages. It was not clear to me which you meant. Perhaps it was just the way I read it at the time.


Then you have a much higher bar for pedantry than I do. I get annoyed when someone makes a brief, general statement and gets called out for not carefully softening it to near pointlessness. In general conversation, I'd prefer it if people assumed most statements were generalizations that are statistically significant and not proof assertions that are either True or False. Otherwise, discussion becomes extremely watered down with every statement swamped in disclaimers, softeners, exceptions and alternatives. Err... I meant "most statements except in specific situations where you are..." :P


I get where you are coming from, and I also think there is a line where it seems you can't say anything without having to qualify it so much that it becomes annoying.

It was not clear to me whether gcp's statement was supposed to be limited to a comparison between C++ and Java/dotnet/python (and I addressed that in the post that you responded to). I felt it was worth the qualification for the sake of discussion, and I still don't think it was being pedantic to ask (especially since I addressed the possibility of it being the above comparison). I wasn't just nitpicking for the sake of nitpicking. And my question was a far cry from asking him to "defend a mathematical thesis", IMHO.


An even better question is "faster by what metric?". Once it has been running for a while and the JIT has done its work, it can definitely happen that a Java program will outperform an equivalent C++ program because of the JIT's improved knowledge of the whole program and the dynamic execution environment. C++ can gain much of the same benefit with LTO and PGO, but it's definitely not trivial (particularly PGO) and there's not really a slam dunk win for C++.

Now if the metric is startup time, that's a different story. (Though I believe there's been a lot of work on hybrid AOT/JIT since I left the world of managed languages, so maybe things are better now.)


> C++ still produces the fastest and most memory efficient programs.

Which is the #1 requirement for a bunch of applications. I can feel I want to go back...


random crashes

Which means whoever wrote the code was doing it wrong. Which is not that strange given C++ really did (and still sort of does) make it easy to make certain mistakes. But which could be countered by a better understanding and learning of the pitfalls.

Good news is: all of that got in my opinion better since C++11 and beyond. Lots of cruft still there of course, but most of the time you don't need to touch it. And if you do have to, you're ither doing it wrong, or there's a really good reason for it. Should you start from scratch, using a proper book or tutorial, you shouldn't have too much problems. If you don't start from scratch, you're going to have to spend extra time in forgetting a bunch of things you learned about C++. I've seen more than a couple of programmers really struggling going from C to C++03 (and as a result writing C with a class here and there and, god forbid, even using a vector or string or algorithm), and from C++03 to C++17 is not that different.


If you had 'random crashes', you probably weren't that good with C++ ...


It's definitely getting easier, but I still wouldn't even consider C++ without valgrind or similar watching over my back; and I've been writing C++ since 1995. Accessing a variant value as the wrong type, dereferencing empty smart pointers and accessing non-existing elements in collections and many many more cases will still segfault; and I don't expect that to change since it lacks that level of security by design. That being said, it's still the most pragmatic language around; the only language that allows me to choose my own level of crazy.


I don't find null pointers any worse in C++ than in Java or C#. Seg fault or a NullPointerException that you can't do anything useful with, take your pick.

Buffer overflows, now, those are a special pain in C and C++. In many applications you don't need to work with arrays directly, though; and when you do need to do a lot of stuff with arrays, you probably also need it to run fast.


Exactly! C++ is a language where you are free to choose level of safety.

None of your examples are a fault of the language - it is a fault of developer not doing necessary safety checks.


The point is: some languages have capabilities to take some classes of errors out. A language with GC and heap-allocation only makes it hard to get access-after-free-style errors. Languages with bounds checks on all elements reliably crash (throw an exception) instead of showing "random" behaviour on bad reads. Of course all of that comes with a cost, but for many domains that works out ...


I take it you've never made a mistake programming before then? A relatively trivial example is passing by const reference [0] While it's fairly clear in this example that you're getting a reference to a local variable, it can easily slip through if you pass something through a level or two of a function. Note there's no compiler warning for this. It also (probably) won't show up until you actually try and use St.m_x at some point, which may be in a very different place to where it was initialised. In most cases, if it shows up in an optimised build, you'll get next to 0 useful information from a debugger/stack trace.

[0] https://godbolt.org/g/XTh5Mv


My beef here is with the word 'random'. Mistakes don't make for random crashes - hard to trace perhaps, but not random.


> not random

Not so sure about that. Here's a mistake: have a floating point variable somewhere and then don't initialize it. On it's first use, multiply it by 0.0. What do you think the chances are the result is 0.0? Hint: nan * 0.0 == nan, and there are many nan representations out there, so it solely depends on what pattern the memory location for that variable is initialized with. So unless your compiler created a bunch of code to initialize the memory for you, which it does not always do, I'd consider that pretty random.


Well, yes, but it is randomness of a mistake - not randomness of the language. If you are going to shoot yourself in the foot, I guess the wound would be pretty randomly located - but that is not the fault of the gun manufacturer.


Yeah, blame the user for the effects of broken design.


I think calling it broken design is quite unfair. I'd say to constructively criticize a programming language you'd have to bring much more to the table. You can point to specifics in the syntax, grammar, rules etc along with an argument as to why they are problems.


It is not broken, it just assumes more responsibility than most developers are willing to accept.


Really? You accept responsibility? In what way has any developer ever accepted responsibility for bad code? When an engineer is negligent and a bridge collapses, they are responsible - there's a whole system of insurance around it. When a developer is negligent and user data is compromised, do they take responsibility?

No.

Should the developers of C++ take responsibility? Or just the consumers of the language? Why is one different from the other?

This entire argument that the users of C++ are at fault for everything is absurd. Users suffer for it, and no one truly takes responsibility.


In your example, the cause of the collapse would be that developer drove a tank onto the bridge and didn't bother to check the weight limits beforehand.

If you forgot to initialise the variable before using it - it's your problem, not the problem of the language. This is a feature of C++, not a bug. It is well documented, it is expected, and it is there for a good reason. And if you are running into this issue all the time, perhaps C++ is not for you.


> In your example, the cause of the collapse would be that developer drove a tank onto the bridge and didn't bother to check the weight limits beforehand.

I don't see how, at all, and you haven't addressed how this somehow makes the C++ developer different from an engineer.

I think your analogy is absolutely imprecise.

And the people on the bridge aren't going to care.

> If you forgot to initialise the variable before using it - it's your problem, not the problem of the language.

Wrong! It's very clearly not the developer's problem, because they don't take responsibility. It's the end user's problem, because they're the ones who get hacked.

> It is well documented, it is expected

Oh, please. As if any C++ developer can spot every instance of UB.

> it is there for a good reason

Is it? This is an unfounded statement. Is there ever a good reason to read from an uninitialized variable? It's UB, so it seems like the language is telling you explicitly that it is not a good idea. But the language gives you not way of formally verifying that you don't.

> And if you are running into this issue all the time, perhaps C++ is not for you.

Alternatively, perhaps C++ is not for any human, as it's clearly far too complicated to reason about.


"When a developer is negligent and user data is compromised, do they take responsibility? No."

^ Well, replace "negligent" with "makes a mistake", and I've taken responsibility plenty of times. Situations happen. You do your best to mitigate mistakes in code within the constraints of your situation, but you don't always catch everything. Corner cases arise that you did not foresee, etc.

I have missed things that have caused user data corruption (or a similar problem) before, and when it was discovered I apologized to the user(s), fixed the problem and moved on. It's an imperfect world and I'm not omniscient. Yeah plenty of developers would just patch it, move on and not tell anyone, but there are a lot of us who care about the people we write code for and do the right thing.


If you resurrect objects in the GC finalizer, you probably weren't that good with Java.


It's significantly easier to be "bad" with C++ than it is to be "bad" with Java.


> If you had 'random crashes', you probably weren't that good with C++

My own skills dont necessarily matter. If you're working on a project with 100 devs, it only took one bad piece of code (or a bad library) to bring the whole thing down - which is a main downside to the language.


Isn't that true in any language, though?

The only major additional problem C and C++ bring to the table is that some bugs manifest as subtle memory corruption, so the cause of the crash isn't immediately obvious.


Scanning through the list of features, one I dislike is selection statement initializers:

if (init; condition) {}

(Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p030...). It just seems like clutter. I generally prefer when languages discourage side effects in a branch condition.


That's sorta the point... the init isn't the branch condition. It gives terser syntax to a common patter where you want to scope something into the body of an if statement.

  {
    std::unique_ptr<T> x = foo();
    if(x->something()) {
      // use x
    }
  }
  // x out of scope, destructed
becomes

  if(auto x = foo(); x->something()) {
    // use x
  }
  // x out of scope, destructed
It's makes it easier to read the lifetime of x (an important thing you have to manually keep an eye on in C++ in many cases), and to determine what is in scope outside of the if statement. It's analogous to for-loops vs. doing loops "manually" with while. You're just used to for-loops by this point (if you don't like for loops then ok :).)

C# is also getting (has got?) this feature.


To expand on this for non-C++ programmers, scope is important in C++ because it is used for resource management via RAII [1].

In most languages, in most cases, scopes within a function are used to enhance readability rather than to specify program logic, so a feature like this would add more complexity than it removes.

[1] http://en.cppreference.com/w/cpp/language/raii


What makes this really nice is that the variable is also still in scope in the corresponding else block.


If I'm reading the paper right, the init statement could be any expression-statement or simple initialization. So, modifying unrelated, externally scoped variables in the init would be legal. I don't see this improving readability.


It's no different than the init and conditional parts of a for loop. Do people abuse for loops to do unrelated tasks? Not really.

It does improve readability. If you've ever had to have a series of conditionals in their own braces to keep the init variable in its own scope, then you have a use for this. The alternative might be having foo1, foo2, foo3… all in the same scope, and it's too easy to use the wrong one. This keeps things specifically constrained to the scope in which they are used, which improves safety and correctness, and I think also readability once you adapt to it.

Yes, it could be abused, but I don't think that's a reason not to use it for its intended purpose.


People mess up for loops a lot! That's why range-based for and the STL algorithms library are so useful. I agree having multiple fooX variables in scope is bad. In practice, I've found that either many of these return types are identical, so variables could be reused, or the logic flow could be organized in a more straightforward way.


I wouldn't want to reuse a variable for multiple purposes though; that can lead to unintentional use of the wrong value. At least this way you ensure that can't happen.

And agreed that people mess for loops up, and range based loops are better. My point was only related to the syntactic precedent for coupling an initialiser and conditional in a statement.


Generally, variable reuse is bad. But for something like an error flag that immediately causes function exit and is never referenced again, I wouldn't raise an objection in a code review.


Well, "#define if while" is also legal, and doesn't improve readability either. Like most features, when abused, they're a liability.


It's consistent with for (init; condition;) {} and solves a problem like:

if (std::vector<int> v = f(); !v.empty()) { // Use v }

without requiring an extra compound statement to limit the scope and lifetime of v.


I agree that it's consistent, I find it easier to read when the branching condition is front and center. In 99% of cases I've encountered, the scope of the branching condition variable doesn't matter. When it does, an extra set of {} defines a scope clearly.


An extra set of {} seems to be clutter to me.


That plus extra indentation. It also obscures the intent since it's not necessarily unambiguous why those braces are there? Is it just to group logically related code (without putting it in a separate method/function) or is it because you're relying on RAII -- it's only possible to tell by searching for destructors on all the classes you're instantiating.


I really hope I can soon replace

  add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-std=c++1z>)
with

  set (CMAKE_CXX_STANDARD 17)
Note: we had a green field application that started with an empty Emacs buffer so figured we could go straight to C++17. I doubt this is a particularly common case right now.


Supported since CMake 3.8!


Yeah, CMake supports it and G++ accepts it but Clang++ doesn't yet, and we compile with both compilers.

Edit: and LLVM 5.0 was released today; clang now accepts the flag!


There are some nice things in there, but the destructuring looks a bit odd:

  struct S { int x1 : 2; volatile double y1; };
  S f();
  const auto [ x, y ] = f();
So it's just ordering based, I can't pull out one member by name?


C++ already had syntax for pulling out one member by name: ;)

    const auto x = f().x1;


I'm not sure what the wink means, but I think gp might be talking about destructuring like what you'd find in Javascript:

  > const {a, b} = {a: 'hey', b: 'there'}
  undefined
  > a
  'hey'
  > b
  'there'


It's yet another feature stolen from Python.

Next version maybe they will even allow stuff like

  [x, [y, z]] = f()
or

  [x, y, z...] = f()


These ideas are a lot older than python, about as old as multiple return values.


C++ has tuple<> for this.


it has to work with unnamed tuples:

const auto [ x, y ] = make_tuple(1, 23);


Tuples are ordered though. I don't usually think of structs by the order the properties are declared - I usually think of them by name.

I am, admittedly, not primarily a c++ dev though. Are structs typically ordered data structures in c++?


> I don't usually think of structs by the order the properties are declared

In C++ you have to, since it's guaranteed by the language that members are initialized in order of declaration (within the struct). And, like C of course, it also determines memory layout, padding and alignment

> Are structs typically ordered data structures in c++

Yes, and compilers like Clang even let you inspect their memory layout


> Tuples are ordered though. I don't usually think of structs by the order the properties are declared - I usually think of them by name.

Think for instance of a 2D point structure. There are tons of implementations, all with different naming conventions ; or sometimes storing them in an array. This allows to just do :

    auto [x, y] = someRandomLibraryPoint();


There is no struct here.

x will be an independent variable which will take the first value from the tuple, and y the second one.


His point is that it makes sense to destructure in order for tuples, but what makes sense for structs is destructuring by field name.


Does anyone know the status of UFCS?

I know it's not in C++17, will it be in C++20?


Does it have coroutines? Python has had them since 2.5 (2005) and Golang has obviously had them since the beginning.

When will C++ finally catch up?


Catch up? Everyone has their favorite feature; I could ask you when Python is going to catch up with C++ on static typing, or when Go is going to catch up with C++ on generics.

Anyway, Go goroutines and Python generators are very different beasts. Because the term "coroutine" can refer to very different things, implementing any single interpretation of the term would likely leave proponents of other interpretations disappointed. Coroutine support for C++ has been in progress for several years now, and some fundamental design questions have been quite controversial. However, there's now a Technical Specification out [0] and, if all goes well, it should be on track for inclusion in the C++20 standard.

[0] http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/n4680.pd...


When will Python finally get rid of the GIL and offer AOT compilation to native code?


To be fair, none of these would be part of a language specification, only a specific implementation.


Something something "export" for templates cough gargle


Gesundheit!


There are already coroutine libraries for C++. I've used folly's Fibers with great success.

https://github.com/facebook/folly/tree/master/folly/fibers


Boost has 3 different coroutine libraries (Boost.Coroutine, Boost.Coroutine2 and Boost.Fiber).

Boost.Fiber has Go-like channels[0] for example, and Boost.Coro has facilities for using coroutines like generators (by using Boost.Range)

[0] http://www.boost.org/doc/libs/1_65_1/libs/fiber/doc/html/fib...


You do realize that holding up Python as an example of modernity based on only taking about 15 years to implement an idea from the 1950s is a bit odd, right?

For that matter whole game is more than a little silly.



This is a strange comment. Co-routines in C++ will be very different to co-routines in a VM language.


Actually co-routines in Kotlin and Scheme are quite similar to C++ idea.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: