Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: Name good examples of Modern C++ usage
82 points by marenkay on July 8, 2017 | hide | past | favorite | 43 comments
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 :-)




Since Dolphin-emu came up, in the realm of emulators I have to mention byuu's Higan emulator. It's got some really cool stuff going on, though the perfectionism is a bit intense (it has its own STL-replacement!) YMMV for some of the decisions, but seriously, there's a lot of great stuff. I always cite the ARM instruction decoder as being my favorite part, but there's really a lot of great use of cutting edge C++ all over the place. Byuu seems to adopt C++ features roughly as soon as GCC and Clang support them, or maybe sooner...

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.


Oh yeah, one last thing: not an example, but a pretty useful reference- Google's C++ Style Guide.

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.


Note that the style guide contains recommendations specific to Google's situation (they note this in the guide). For example they recommend against exceptions because by the time the style guide was written they already had an installed base. Had they started over they would use them.

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.


To be honest, I still don't use exceptions. They don't really feel all that great in C++, and I think Go has solidified my anti-exceptions attitude. A lot of the STL and standard libraries and even many third party libraries also abstain from using exceptions since they behave poorly across library boundaries on many platforms thanks to the lack of properly standardized ABI, and of course because the standard libraries try to be as unassuming as possible. Of course, you can still more or less safely use exceptions if you control your ecosystem, but since this is the case, it gives a (pardon my french) PHP feeling of inconsistency in many ways.

There may be compelling reasons to use exceptions, but if there were I think they have to be quite compelling to overcome the limitations.


This is one of the reasons I never liked to work with certain C++ teams back on my C++ days and drifted to other languages that don't allow to turn features off, because I always enjoyed having exceptions and RTTI turned on.


Really? I've used RTTI a handful of times but to be honest with you aside from debugging I very rarely had a use for them. I think C++ could benefit from more powerful reflection, though. Do you have any simple examples of exploiting RTTI to solve problems?


Yep dynamic_cast is not guaranteed to compile with RTTI disabled.

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.


> since they behave poorly across library boundaries on many platforms thanks to the lack of properly standardized ABI,

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?


Because throwing an exception can bubble across library boundaries, including over C-style APIs that are fully compatible across library boundaries.


If your C-api throws and then doesn't handle exceptions, then it's not a C api, it just happens to use the C ABI.


It's more complicated than that, though, because a C library seldom controls the callstack. Exception throwing is viral.

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.


I said not handling the exception, not that one shouldn't use exceptions. Handling, here, could also mean using callbacks so the C code (using the api) can customize things.

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.


Of course. I understand that. But I am arguing that this kind of sucks.

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.


I can't really comment on the GCC windows stuff: I do software on Linux, and if I'm on windows then I use VC++ (Or a good programming instead e.g. F#/C# usually). VC++ is modern enough, so the above issue don't even apply very much.

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


Yep. I mentioned it's not an issue anymore, but back when VC++ was less modern and GCC didn't have SEH support, life was much worse.

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.



Doesn't contain many "modern" features, but nevertheless, probably the best C++ code I ever saw, and it is usually hard for me to give any praise for C++.

Stockfish chess engine (currently 1st place by Elo). I am really impressed:

https://github.com/official-stockfish


Kenny Kerr's dx.h library[0]. He has also written several articles[1][2] that discuss the design of its unique_handle class.

[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


Here's an existing compilation of such work:

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


I would name Eric Nieblers range-v3 library : https://github.com/ericniebler/range-v3 - amazing stuff.


Snackis may be considered more post-modern than modern, I prefer open structs and free functions to classes and methods and simple/custom to over-engineered; but it depends on plenty of new C++-features to do its magic: https://github.com/andreas-gone-wild/snackis


Can I post mine :)

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 :)


LLVM is a very interesting project when it comes to C++ style. It is very much modern C++, except that they implement quite a lot of stuff themselves (e.g. RTTI and dynamic_cast/dyn_cast). Certainly very well engineered, but I wonder whether some of the techniques are strictly necessary (It works well, so I'm not complaining)




+1 to Folly for elegant modern code, but their use of shared pointers is nothing to be proud of, at least in the C++ world.


I've yet to find a valid use for a shared_ptr. A unique_ptr is great to use for polymorphism but I've always thought if you can't figure out what owns what in memory in a program, you haven't planned it very well.


Then I imagine you never had the fun of feature driven software development by consultants at enterprise level.

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.


I understand that you have legacy requirements to support elements that previous developers have used, but that doesn't explain why someone would use a shared_ptr in the first place. The great thing about unique_ptrs is that they take away the manual memory management. It is a complete PITA not having them. I can even see the use in weak_ptrs. My issue is with shared. I can't see how their use wouldn't lead to larger problems in code.


Well, Windows projects with COM everywhere, and no access to the complete code, with responsibilities scattered across feature teams.

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.


I 'learned' (bumbled) through c++ almost 30 years ago. I formally learned both c and c++ properly through uni more recently. I'm not sure I'll ever use another language if i want to build something that is complex but i need to be really fast. I love c but the more complex the problem, the more infeasible it gets to use. But c++? There isn't a processing problem that you can come up with that you couldn't use c++ to resolve it with. Love the language.


I've been impressed by the Sea star Project (http://www.seastar-project.org/). It was developed to build a high throughput database (ScyllaDB) but has since been used in several other projects. I recently spent some time evaluating it as a starting point for a new application.

Also, a fan of the elegance on display is this serialization library: https://github.com/msgpack/msgpack-c


LLVM is my favorite C++ project. (Together with clang and swift)




- variadic template arg (static va_start/end)

- rvalue&& (avoid few copies)

- enum class (enum with a size and a namespace)


I'm not a C++ developer by trade (mostly C#) but this looked compelling when I was looking to create high performance Windows app middleware: https://github.com/microsoft/cppwinrt


Ladies and gents, thanks a lot; those are some nice starting points!



That's very far from Modern C++. It's more the C with classes style of C++.


I suppose that depends on your definition of modern!

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.



ha. As a former contributor to dolphin-emu (very minor though, too busy :() I'd caution against calling it a "good example of Modern C++." It's an amazing program written by super smart people, but some of the things that lurk in there can be quite messy.

Of 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.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: