1. 26

  2. 14

    Modern C++ is certainly better than pre-C++11, but I don’t think it’s going to ever be something I actually want to use until they start removing misfeatures.

    1. 7

      Fully agree. This article seems to be addressing a criticism of C++ which I don’t think anybody is making – that C++ doesn’t have enough features.

      C++ has enough features. My problem with it is that it has so many features that 5 people working with one C++ codebase can be essentially working with 5 completely different languages.

      1. 3

        Unlikely misfeatures would be actually removed, but there is effort for cpp core guidelines, basically a ‘sane’ subset of modern c++. Part of it is already in clang-tidy, and if I recall correctly, the idea is that it would become the default mode in compilers at some point (although I might be wrong here).

        1. 2

          The issue I have with Core Guidelines is that the majority still can’t be enforced by the compiler (there are only some warnings for some things, and even then you may still need to put appropriate keyword/attr to get them).

          This doesn’t solve my problem with C++ of having to remember to be careful about so so many things (“Remember that if feature X is used, then do Y, except when Z”). If I get them wrong, then it’s my fault for not remembering and adhering to all the guidelines.

          1. 1

            Is there at least a flag?

            1. 1

              I think it is still work in progress (without a strict deadline) hence no flag yet. But they mention clang-tidy and CppCoreCheck from Microsoft.

              I agree though that compiler flag is very important to have, reasonable defaults are very helpful for easier adoption and learning about patterns and antipatterns.

        2. 11

          I use C++ occasionally now, and more so in the distant (pre-C++11) past. To say that it’s improved is an understatement: pure C++11 is light-years ahead of earlier editions.

          Three problems, though:

          • Documentation is still lacking, it would seem. I have yet to find a concise and accurate document explaining how to write your own type-safe iterator-aware class. I know it exists, but even the 800-page A Tour of C++ by Stroustrup doesn’t tell you how. (I realize it’s a “tour”, but, in my defense, it’s a multi-hundred-page tour and since iterators and custom data types are such a core part of the language, I would expect it to be covered). There are Stack Overflow and other examples but a huge number of them rely on deprecated features.
          • Compiler error messages are still difficult to understand and compilation times are (relatively) long. Supposedly great strides are being made in these areas.
          • There’s still a lot going on. I realize that every language has its nooks and crannies but, still. TFA talks about how C++11 has helped this some, but most of the old mishmash of features are still there, the majority of codebases still have those older features….
          • RAII and smart pointers are awesome, but they’re library features, not language features. They’re not checked at compile time and memory management is still a footgun. It’s fine as long as you stick to convention, but the instant you deviate from it the compiler won’t warn you (usually) and the runtime won’t help you.

          Now, as I stated above, C++ is not my primary language, but I use it from time to time, so…correct me if I’m wrong.

          1. 3

            I have yet to find a concise and accurate document explaining how to write your own type-safe iterator-aware class

            If you mean something that can be used in a range-based for loop, check cppreference:


            Key text would be for which begin and end member functions or free functions are defined - they need to return something that acts like an iterator (supporting pre-increment and dereference operators, and equality comparison). I know the text is pretty dry and technical but cppreference really is a good source of information.

          2. 7

            C++ in 2019 is definitely an improvement on C, but a lot of the modern features simply don’t compare to other modern languages. With Rust or Swift I don’t feel like I’ve gotta cook my program in AFL for a week to know I’ve got all the segfaults out. C++17 features that aim for zero cost abstractions, like optionals or smart pointers, only seem to target runtime wall clock cost, and not the cost of finding out there’s a way to dereference a std::shared_ptr<Whatever> that happens to be null.

            1. 5

              I’d love to use C++ as long as I could avoid using CMake

              1. 4

                So, many people are spending a huge effort to make C++ better. I’m not sure this sounds as good as it is meant to sound. Also, C++ evolves quickly, giving you new advanced features every few years, while keeping backwards compatibility. I’m really not sure this sounds good either.

                My takeaway is that C++ is huge, and all the effort going around it is a sign that it requires that kind of effort. The vibe I got from this post was that it feels good to be part of a big community doing big things. Sure thing. But one thing that definitely does not feel good is huge artefacts. The C++ specification is at least an order of magnitude bigger than it would need to be if the language was invented right now. That language sits on a huge pile of legacy code and languages, starting with K&R C. It inherited almost all of its mistakes, forcing the community to spend herculean effort to compensate for them. I commend the effort, but I do condemn the need.

                C++ is best at one thing: using existing C++ code. The other niches have better alternatives.

                I still use Qt to write GUI applications, mind you. Because Qt is a huge freaking useful pile of code, I’d be stupid to ignore it. At the same time, let’s not forget that’s how path dependence happens. If we were to rewrite Qt from scratch now (will never happen, I know), C++ would likely not be the best choice.

                1. 4

                  As someone who is falling in love with programming all over again after dipping my toes into C++14, this article captures a lot of what’s changed from when I wrote C++98 back in the mid 00s.

                  #include<c++> is a pretty cool movement too.

                  1. 3

                    I am one of those rare C++ superfans (I even like pre-C++11) and the language is definitely growing up and growing up in a way where you need grown up tooling as well.

                    For the last two decades I’ve mostly been a vim and Makefile kinda guy but that is too “old fashioned” for new people trying to learn C++ now. Building and packaging are a problem that the C++ community seems to be solving using CMake and header-only libraries. Even using auto really requires a good IDE with some “intellisense-like” intuition so you can see what type you really have and what operations you can perform.

                    My personal pain point in C++ at this time are long compile times. The most recent project I was working on required use of a regex library. I looked at C++ regex and pcre and eventually went with C++ regex but may switch back to pcre for both improved performance and compile times.

                    1. 3

                      Even using auto really requires a good IDE with some “intellisense-like” intuition so you can see what type you really have and what operations you can perform.

                      CLion seems to do a good job of you’re running GNU or Mac. Throwing it out there since it took me some time to find.

                      1. 3

                        For the last two decades I’ve mostly been a vim and Makefile kinda guy

                        Sometimes I wish I could break out of this mold. My problem with IDE’s is that eventually, no matter how good they are, you have to drop into the shell…so I just keep it to the editor-shell-compiler triple. Maybe that’s the source of my reluctance to do more C++, I dunno…

                        1. 2

                          It’s not that weird to switch between a shell window and IDE window. I actually prefer the hybrid approach. An IDE trying to do everything has way too many buttons, menus, submenus, and options. 98% of the time I only use search, jump to definition, run test under cursor, or merge tool. Anything else and I’d rather get exactly what I want on the shell anyway.

                          1. 2

                            Only needing four things means you’ll learn an IDE faster than anyone. Then, you have everything else available on an as-needed basis. Some IDE’s also have lots of third-party plugins, too.

                        2. 1

                          Weird that you’re seeing long compile times. I’m seeing the exact opposite. 8000 LOC project, so not exactly large, but it pulls in Boost and CLIPP (a 6000 LOC header-only arg parsing lib) and it takes under 20 seconds to build on a single core xeon VM and under 11 seconds to build on my workstation.

                          1. 5

                            It might be relative. Some languages compile thousands to tens of thousands of lines a second. Anyone experiencing C++ after one of them would be saying “WTF…?!”

                            Then, there’s the more ideal situation like with Common Lisp where you have a REPL for instant results, quick compiles on per-function basis, and fully-optimized compiles. Whatever you need. Most ideal I advocate for is where program analysis and optimization happens in the background as programmer continues to work on whatever is still in their head.

                            1. 1

                              It’ll depend on the project, what you’re changing, and how it’s structured. If you change important low level headers in a large project (6-10 million LOC), you might see a 30-45+ minute build time.

                          2. 3

                            I really like the new features they’ve introduced (lambdas, some syntactic sugar for classes, constexpr) but I find the size of the language overwhelming. The language “editions” used to manage Rust versions would be great.

                            One thing not mentioned in the post is that debugging a template-heavy C++ program can be a jarring experience. Much code relies on the fact that the compiler inlines and optimizes away tiny functions, but in the debugger you need to jump through all of them. This can also make debug builds very slow (especially the Eigen math library.)

                            I suppose you’re not supposed need a debugger in the first place if you write C++ the modern way, so I don’t see the debugging story getting better in the future.

                            1. 2

                              I suppose you’re not supposed need a debugger in the first place if you write C++ the modern way, so I don’t see the debugging story getting better in the future.

                              I’ve never programmed a language for more than a day and not wanted a debugger. Modern C++ isn’t an exception.

                            2. 2

                              While I personally do not use C++, but I’ve never considered the language being the source of the problem. Rather how it is used.

                              It has a lot of feature for quickly climbing up in term of abstractions, but it has a fallacy:

                              • I want to organize my code
                              • I spread my code and data into classes
                              • I now need getters and setters
                              • Ok, I’m all good, now I can write my imperative program in C++ through a layer of OOP.

                              C++ programs I dislike mix the code and the organization of classes all over the code, therefore hiding the real work.

                              C++ programs I like offers a tiny OO interface wrote over larger imperative, library-style code.

                              Reminder: the developer organizes the code, not the language.

                              Conclusion: Write primitives plain C (maybe with smart pointers, vectors, if you like them …) without OOP at all, and only when you are done, think of a minimal API that call the primitives you just wrote.

                              1. 4

                                Note that that goes against what I’ve been told at school, where they teach us to make use of classes and OOP because it saves time rather than because it can provide joyful APIs.

                                I use functions to save time, functions… ;)

                                1. 3

                                  Functions, then modules, then classes is how I do my Python. You’re not alone in thinking “Functions first” - while OOP is nice, it’s waaaay overused, often appearing inappropriately at the start of a project that should’ve played with functions and structs (Python namedtuples) first and foremost. Then again, I love immutable data structures first in order to reduce reasoning about who mutates what. 😁

                              2. 1

                                IME the “Rust compiler fighting me” thing exists in C++ (try making a class that’s not copy-safe, and then being forced to learn how to implement a correct copy constructor for it with 2000+ lines of template errors), but I have the option to not do that (with pointers, new, and delete), also, which as a hobbyist is pretty essential to maintain long-term enthusiasm.

                                Also, the longer I work on a project, the more chances I have of eventually going back and fixing some bad code, versus feeling discouraged and giving up early.