1. 22
  1.  

  2. 10

    C++ is the only language I’ve worked in, where it is completely normal (and often preferred such as in the games industry) to completely ignore the standard library. It’s also the only language I’ve worked in where the standard library is not written in anything resembling a style you’d find nearly any normal code base written in.

    We have a committee with 300+ members. It seems that essentially every member has a feature or two that they’d like to get into the language, and many have several.

    This is the problem. I have to study this language constantly to stay up-to-date and know all the in’s and outs of bizarre rules and in that time I could have done so much more with my life.

    If we are not careful, C++ can still fail

    It’s already failing. I believe it’s pretty much dead on the table, with current projects keeping it alive. I take a lot of flak from a lot of people I know for still being the “C++” person. I love the power of the language, but can’t honestly recommend anyone use it over any other one. C++11 was a great step in the right direction, but the burden of more and more complexity from pet features while not helping me deal with the real complexity issues (#include’s, build systems, usability issues with the standard library) has me really struggling to keep wanting to put in the effort.

    1. 2

      C++ is the only language I’ve worked in, where it is completely normal (and often preferred such as in the games industry) to completely ignore the standard library. It’s also the only language I’ve worked in where the standard library is not written in anything resembling a style you’d find nearly any normal code base written in.

      This hasn’t been my experience. Other than one place with ancient code that avoided templates, I’ve never worked on a C++ codebase that didn’t use the standard library. I think a few high profile talks at C++ cons popularized the idea that the STL was too slow, but for most use cases it’s not really true.

      1. 10

        Gamedev reasons to not use the STL include:

        • Doesn’t play nice with custom allocators
        • Insanely bad APIs. C++ committee people love the everything is an iterator model but it’s just crap to use
        • Insanely bad compile times
        • Insanely bad debug perf
        • Insanely bad compile error messages
        • Insane algorithm choices. e.g. C++11 RNG stuff
        • Insane implementations
        • Spec enforced bad runtime perf. e.g. std::unordered_map is specced to be bad so all the implementations have to be bad too
        • Certain older consoles had “variable” implementation quality
        • It’s like hundreds to low thousands lines of mostly trivial code to write your own array/string/hashtable/etc so why not
        1. 1

          Doesn’t play nice with custom allocators

          What do you mean by this? Every single collection type in the STL supports custom allocators– what about their implementation is bad?

          1. 7

            STL custom allocators are passed in as template parameters so they can’t have state, which makes them pretty much unusable.

            1. 4

              It also means containers with the same types but different allocators are different types.

          2. 0

            I’m not arguing that it’s a great library, just that most projects don’t bother replacing it. It might be standard practice for game developers, but they’re a small niche.

            1. 1

              It might be standard practice for game developers, but they’re a small niche.

              I’d bet even money that the majority of C++ software written these days is game code.

              1. 2

                I’m skeptical, but would be interested to see data if you have any.

                My own evidence is anecdotal - I’ve worked primarily with C++ for 15 years and have never worked on or even been contacted/recruited by any game companies. I haven’t even worked with anybody (to my knowledge) who’s worked on game software. On the other hand I haven’t been seeking them out, so who knows.

                1. 1

                  Steam has a pretty good list of programs.

                  1. 1

                    Do they have any numbers on how many of those games are based on Unity? The game logic in Unity-based games is written in C#, so I’m sure that would make up a good chunk of new games code written nowadays.

          3. 8

            In my experience, its’ a good point.

            • When I was at EA, we started using C++ but not STL. This was a long time ago, but I’m NOT sure STL got significantly better for the console use case.
            • At Google string is not std::string. I think the interfaces were slightly different, although I don’t remember the details. This is tens of millions of lines of code linking against a non-standard string, and it’s one of the most common types in the codebase, etc. As far as I remember, the reason was performance and maybe code bloat.
            • The fish shell is one of the only shells written in C++, but it explicitly avoids STL. Oil might go that way too. (Right now the only thing we use is std::vector as an implementation detail)

            STL also uses exceptions, and many codebases compile with those off, e.g. all of Google’s.

            There was a recent cppcon talk by Herb Sutter which noted that the exceptions issue essentially bifurcates the language. And he surveyed the audience and I think at least half of people had SOME restriction on exceptions in their company.

            When you write all of your function signatures differently, you’re almost writing in a different language. Those two styles of code are cumbersome to bridge.

            1. 1

              STL also uses exceptions, and many codebases compile with those off, e.g. all of Google’s.

              I’ve never worked with C++ - what does it mean to have exceptions off? You’ve disabled the possibility of raising / catching exceptions in the language? I’ve never worked with a language where something like that would be possible. Is error handling then done through a (result, maybeErr) = someFunction(); if (maybeErr) { ...} pattern?

              And why do people turn exceptions off? Does it mean you then can’t use any library that uses exceptions (like STL)? Doesn’t that mean lots of libraries can’t be used together with lots of other libraries?

              1. 3

                Yes, C++ compilers generally allow you to turn off exception support. All the code that deals with handling exceptions is discarded; any code that attempts to raise an exception instead crashes the entire process.

                One reason people turn off exceptions is for efficiency - when an exception is thrown, all the local variables allocated up to that point must be deallocated, which means there’s a bunch of bookkeeping that always has to be done, even though it’s almost never used.

                Another reason people turn off exceptions is for simplicity. If you’re trying to understand what a given function does, you have to understand the control-flow pattern, and more complex patterns are more difficult to understand (Cyclomatic complexity). Exceptions add an extra “exception thrown” edge to the control-flow graph from every line of code to the exit, which makes things much more complex. In garbage-collected languages like Python or Java it’s not as big a deal, because most things will get cleaned up eventually anyway, but C++ expects you to care about more details.

                Generally C++ code designed for “no exceptions” mode will make functions return error-codes, yes. Libraries that use exceptions aren’t incompatible - they just crash the process when something goes wrong, as I said - but if a project is designed for “no exceptions” then it would probably prefer libraries designed under the same constraint.

                1. 1

                  Thanks :)

                2. 3

                  Yes if you turn it off then the code just crashes. So you don’t want to use throw anywhere.

                  C and C++ error handling strategies are very diverse

                  • errno style which is a global / thread local
                  • boolean result and out params: bool myfunc(const Input& i1, const Input& i2, Output* o1, Output* i2)
                  • Result/Maybe objects (this is more “modern C++” that depends on templates)
                  • Exceptions

                  People turn off exceptions for at least two reasons:

                  1. Because they don’t like non-local reasoning. Classic article: https://www.joelonsoftware.com/2003/10/13/13/
                  2. Because exceptions bloat the generated code with exceptions tables. This may matter on embedded systems.

                  To answer the other questions:

                  1. You can use STL, but not in a way that throws an exception. For example, you have to check that a key is in a map first, rather than let it raise an exception.
                  2. Yes, lots of libraries can’t be used with others. But many codebases are written in a style where exceptions can be “local”. Most big codebases are a hybrid of C and C++, e.g. Firefox, Chrome, I assume Photoshop. So they use C error handling in some places but C++ in others. For example OpenSSL and sqlite are all C, and use C style error handling, but they’re often linked into C++ programs.
                  1. 1

                    So, C and C++ error handling strategies are really very different.

                    errno style is only used in C, and in practice is rare outside of the standard library and other very very old libraries. It’s not used at all in C++.

                    Return codes are used in both, sure. That’s the bog-standard way to handle errors in C or in C-style C++. Result/maybe objects and exceptions obviously don’t exist in C unless you count setjump/longjmp, which is reasonably obscure and doesn’t give you any opportunity to clean up state.

                    Result/maybe objects are not used in C++. You might be thinking of Rust. std::optional<T> isn’t a maybe<T> or a result<T, E>, it’s not for error handling but an alternative to using pointers to represent optional values. There’s nothing modern about something like this, it doesn’t ‘depend on templates’ any more than any other C++ code. Templates in C++ are pervasive. There’s nothing unusual or weird about writing or using templates. They’re as much a normal working part of the language as functions are.

                    1. 1

                      OK what I meant is “result/error parameterized by type”, of which there are many variations, e.g.

                      https://llvm.org/doxygen/classllvm_1_1Error.html

                      It’s more modern than error codes :) And more modern than exceptions.

                      1. 0

                        No, it’s not ‘more modern’ than either. It’s unperformant crap used by people terrified of exceptions because they don’t understand them.

                    2. 1

                      Thanks :)

                3. 4

                  Bloomberg LP uses their own standard library, called the bde.

                  I think when Bloomberg adopted C++, there were some licensing issues surrounding the std library, so they implemented their own. I could be wrong about this – I’m not fully sure what the rationale was, but I don’t think the stl was dropped for the sake of speed. I’m a little bummed the README doesn’t have a rationale.

                  The library is largely compatible with the standard library, with a few key differences. The most important difference is that allocators are passed around as pointers, instead of being specified in templates. Here’s an example of the bsl::vector constructor taking an allocator, here’s an example of a Bloomberg specific bdlcc::Queue taking an allocator. All allocators implement this interface.

                  The bde also has a unique coding style (which I personally find extremely readable), and an almost absurd amount of comments. It’s one of the few C++ libraries that I think is easier to read than it was to write – which is quite an accomplishment!

                  The library also has tons of goodies in it, but isn’t as featureful as boost. My personal favorite the use of traits to encode/decode objects to arbitrary formats, in a fashion similar to rust’s serde.

              2. 2

                C++ itself aside, this is about how you make design decisions, especially large, long-term ones. The quote it starts with expresses a principle I wish was far more widely applied, and it’s only fitting it comes by way of John McPhee, probably one of the best science writers of his generation.