Ask HN: Name good examples of Modern C++ usage
Hi folks,
I'm basically looking into making the transition from a C++98 world into what is supposed to be Modern C++.
Since that is a rather opinionated field I'd love to see a few real world examples. Shoot links to your favourite Open Source project :-)
43 comments
[ 115 ms ] story [ 1474 ms ] threadOf course, I'm sure it has improved markedly since the Google Code days, but still...
That being said, on the other hand, there ARE some nice usages of modern C++ in certain parts. I also like their choice to move to #pragma once - I know it's non-standard but despite pretty intense arguments it seems to do the job just fine.
If you want something a bit more orthodox, or perhaps less depending on how you look at it, on the other end of the spectrum is the intensely engineered "Boost" libraries. Though, to be honest, that may be pushing it as far as "modern C++" goes considering it's written to support older C++98 compilers in many instances.
Qt 5 is one of my all-time favorite C++ projects, although it's again worth noting that it may be pushing it to consider it modern C++. I believe they're currently on C++11 with Qt, so a bit further than C++98. Still... there's plenty to learn about even older C++.
There's more out there, but those are the ones that come to mind for me. I have been out of the C++ game for a while now.
https://google.github.io/styleguide/cppguide.html
I've not read the whole thing, but it looks pretty solid. Of course, there's a lot of highly subjective suggestions, but I can get behind many of them personally.
Having recently started a project from "empty buffer" state we elected to go with C++17 (supported now in both GCC and clang although with some library features still missing). It's worked out well for us, but in my case I approached it as a brand new language rather than an evolution of old C++ (which I'd started in the cfront days and dropped around 2000). In that light it became and expressive and powerful systems programming language that is fun to use.
There may be compelling reasons to use exceptions, but if there were I think they have to be quite compelling to overcome the limitations.
The same also holds for, say, std::string. You can't pass them across library boundaries without a unified ABI. More generally, you can't pass anything STL-ish between library boundaries.
Why make a special case for C++ exceptions?
A valid example would be using a pure, fully ANSI C library with no dependencies in a C++ program, but then, in a callback PASSED to C APIs, accidentally allowing an exception to leak. Then, your runtime will try to unwind the stack and can implode on itself.
There's definitely more valid cases where this can happen, but since C APIs generally do rely on callbacks for many things, it seems like a logical one.
Another case would be C-style dispatch tables like SDLs RW interfaces. Implementing them to interact with C++ classes could definitely cause problems.
Of course, happening to use the C ABI is a valid use case that actually works if you really only use the C ABIs, but once a single exception is raised all bets are off. This kind of sucks.
If you expose a C api, using C++ code that involves exceptions, then the exceptions should all be handled (caught) inside the C++ code. This means that should the runtime start unwinding, it will not terminate the program.
I don't think that it was necessarily avoidable. But for a feature that's seldom used in the standard library and for the stated reasons, a lot of other libraries, it kind of sucks.
There's also other reasons I don't like exceptions, but I'll admit many of them are no longer an issue anymore. On 32 bit Windows, if you were using GCC, which was pretty likely if you were trying to do modern C++ at the time, exceptions were limited to SJLJ and DWARF2 based exceptions which both had their own problems. For one, I'd prefer my production binaries didn't require DWARF2 CFI data. Luckily I believe nowadays in 64bit you can use SEH since it isn't covered by the Borland patent for its AMD64 implementation (do I have that right?)
But I digress. If exceptions were the default and didn't have these issues, I think it would be much better. But since at least some of the issues are still relevant, you simply cannot always use exceptions depending on your needs. And that has an effect on the ecosystem that has led to a lot of mature libraries avoiding them entirely.
I'm definitely not saying you can't use exceptions, just outlining why I don't and why I believe the greater C++ ecosystem isn't all on board for them.
C++ works(TM) with exceptions, AFAIK the vast majority of the ecosystem would use them (Some people e.g. Google and Qt, can't due to existing code). RAII is only really intended to work with exceptions (No return values from constructors, unless! you bodge your own (which you could do, if you were a big organisation))
Edit: Just checked, SEH has been in GCC (64bit) since ~4.8
Now it just has the other aforementioned issues.
Obviously, RAII is better with exceptions, at least in theory. It is annoying having to constantly check if the object is valid or not. However, even the standard library does this, so I don't really think it's uncommon - there was definitely some precedent for RAII without exceptions.
Doing static_cast instead, will open the door to fun surprises if one cannot guaranttee the safety of the pointers given to the library code.
I must add that in those days, we were making use of C++ gui libraries like OWL, followed by VCL and MFC.
Here is a short but useful terminfo parsing library I wrote - https://github.com/agauniyal/termdb
And here is another for console decorations - https://github.com/agauniyal/rang
Recently I worked on a network programming library (still WIP) for college project - https://github.com/c10k/net/tree/develop
And here is a boilerplate to get you all started with Continuous Integration, Unit tests etc etc - https://github.com/agauniyal/cppb
I try to write good code everywhere but since I lack experience so the code might not be perfect. Hence I advise to go light on it. Have a good day :)
Stockfish chess engine (currently 1st place by Elo). I am really impressed:
https://github.com/official-stockfish
Being one, this works like this.
Company X, which main business has 0% to do with software development requires a new feature on an application being used at deparment Y.
They send out an RFP to several consulting companies, the one that gets the gig, sends a few developers, which get a configured devenv from company X IT department and implemente the requested features and go away.
Manual memory management languages became out of fashion in such kind of companies, because it is almost impossible to jump into a gigantic ball of mud, while keeping track of all ownerships.
Thankfully I only use C++ nowadays when we need to bind native libraries into Java or .NET projects, so since 2006 I never had to deal with such horror scenarios any longer.
https://github.com/rigtorp/awesome-modern-cpp
A couple of my personal favourite libraries that I consider modern:
The Parsing Expression Grammar Template Library - https://github.com/taocpp/PEGTL
Beast: HTTP and WebSockets in C++11 - https://github.com/vinniefalco/Beast
The id Tech 4 engine is over a decade old, and like most game engines uses their own data structures. Many additionals to the C++ standard have been in the standard libraries.
[0] https://dx.codeplex.com/
[1] https://msdn.microsoft.com/en-us/magazine/hh288076.aspx
[2] https://visualstudiomagazine.com/articles/2013/09/01/get-a-h...
Edited to fix footnote formatting
- rvalue&& (avoid few copies)
- enum class (enum with a size and a namespace)
Also, a fan of the elegance on display is this serialization library: https://github.com/msgpack/msgpack-c
https://www.reddit.com/r/cpp/comments/489f9l/open_source_pro...
https://www.reddit.com/r/cpp/comments/5sxrun/what_are_some_e...
My list:
SeaStar and ScyllaDB https://github.com/scylladb/seastar https://github.com/scylladb/scylla
Cap'n Proto https://github.com/sandstorm-io/capnproto
LLVM
range-v3 https://github.com/ericniebler/range-v3
Facebook folly https://github.com/facebook/folly
easylambda https://github.com/haptork/easylambda
thrust https://github.com/thrust/thrust
xtensor https://xtensor.readthedocs.io/en/latest/numpy.html