14 ms·
Thriving in a Crowded and Changing World: C++ 2006–2020 [pdf]
- zeroc8 5y agoA well articulated paper by a great thinker. That said, switching from C++ to Go made my life so much easier and more enjoyable that I do not see myself going back to that language ever again.
- hrh 5y agoThere are probably dozens of us that really appreciate his clarity and writing and even his overall design goals for C++, but the language is so inherently loaded with historical baggage, that it is only pragmatic to use newer languages that learn from those successes and mistakes However, I've heard, but can't confirm so don't quote me that it is impossible to appreciate Go and Rust at the same time.
- nly 5y agoThose newer languages will earn their share of historical baggage in time. C++ has the distinct ad/disadvantage that it inherited 15-20 years of baggage from C, as well as carrying 20-30 years of its own.
- hrh 5y agoTotally. There's plenty of people that will argue that Go's historical baggage is in the form of being primitive, and Rust already is a large language. That's the fun thing about these design discussions.
- pjmlp 5y agoExample, comparing C# 10 with C# 1.0, or Java 17 with Java 1.0, including the underlying runtime changes and multiple implementations during the last 25 years (for Java, 20 for .NET).
- tonyedgecombe 5y agoC# has grown quite large over that period however there are large areas of the language that you can safely ignore. Your code might not be as elegant but you won't get tripped up like you would if you don't know C++ well enough.
- pjmlp 5y agoIn which C# version have the foreach variables changed their semantics? Just an example of a possible C# pub quizz question, I have other possible ones.
- tonyedgecombe 5y agoI think it was 4.0 from memory. I'm not arguing that you don't need to think about your code. The early behaviour was what I would have expected, the change was sensible but it's a long way from what you have to deal with in C++. My experience with C++ was a lot of study and practice before I started my first project whereas with C# I was able to dive right in to a substantial piece of work and learn the language along the way.
- pjmlp 5y agoAnother example on how learning the language along the way gets to unexpected results, memory leaks in event handlers, or how HTTPClient doesn't really handle connection pool the way it should in the .NET Framework variant.
- rramadass 5y ago>Those newer languages will earn their share of historical baggage in time. For some reason this truth seems to escape most new language fanboys, in particular; the Rust crowd on HN.
- pkolaczk 5y agoLanguages like Rust and Scala learned they lesson: they don't add features, but also remove or fix features. This is why you have editions or major versions, which are not 100% backwards compatible. E.g. Scala 3 comes with a major redesign of implicits, instead of adding a new way to do the same. Same for Python 2 vs 3. The biggest reason C++ and Java accumulate historical baggage is fixation on near 100% backwards compatibility. E.g. Java 5 added generics, but had to allow using non-generic erasures (List instead of List<T>) so older programs could still compile and run. And now we have to live with this ugliness even in Java 16. Of course dropping backwards compatibility causes a bunch of problems of their own and it is better to try to minimize the impact (Rust editions, Scala 3 vs 2) rather than do a big bang (Python 3 vs 2).
- steveklabnik 5y agoThe key to editions is that they don’t “drop backwards compatiblility”. We have to keep lots of things around forever! They let you opt in to small forms of backwards-incompatible changes while retaining inter—edition compatibility. This means they are backwards compatible in the strict sense of the term.
- tialaramex 5y agoThere are a few other cute tricks (not all of which were in Rust 1.0) to enable this. Rust's "raw" way to spell all symbols is clever. Maybe some day my function named weigh will be a problem because of a new "weigh" keyword. Rust gets to add the keyword but still talk about my function in new editions by just spelling the symbol awkwardly, as r#weigh. This forbids Rust from reserving such spellings (e.g. "r#weigh") as keywords themselves, but that would be so ugly nobody would want to do it. Overall the result is Rust 2021 could even make "new" a keyword if it wanted to, and the old code which uses that symbol name everywhere still works, it's just a little clumsy to talk to it from next edition code. Still, I think it's worth remembering that the edition changes in Rust so far have been much smaller than many changes contemplated for C++ Epochs (or any hypothetical actual C++ feature similar to Vittorio's proposal in spirit). C++ has a lot of problems, and understandably Epoch proponents want to do stuff like ban implicit narrowing coercions, or change how overflow works. Because of how sprawling C++ is these are surprisingly big changes to the whole language, and I don't think that you could pull off something like that with editions. I have a hopeful note though. Maybe C++ can inspire a much more powerful tool than editions, somehow enabling backward compatibility for C++ while also allowing new C++ to be written exclusively in Stroustrup's "subset of a superset" that keeps most of C++'s strengths but loses so much baggage like implicit coercions everywhere. If it's possible, the C++ community have the right people.
- casept 5y agoOh, it's absolutely possible as long as your brain is flexible enough to appreciate both minimalist and maximalist language design. Same goes for C and Rust.
- deleted 5y ago[deleted]
- pkolaczk 5y agoI tried Go and I have an opposite experience. To me Go looked like a very limited, incomplete and non-principled language that makes easy things look easy but hard things ugly or (near) impossible. I put it on the same shelf as Python and Basic. Things like using product type instead of sum type for returning errors really put me off. But that's probably due to past experience and personality type. I mostly enjoy working in powerful and expressive languages: e.g. Rust, Scala, C++. // edit: oh, someone have already said that: can't love Rust and Go at the same time ;)
- maccard 5y ago> Things like using product type instead of sum type for returning errors really put me off. Can you share some practical use cases where the sum type has an advantage? Personally I find go's explicit error type, along with the convention of it being called err everywhere to be really helpful and clear when working through the control flow of a program. What does a more "powerful and expressive" language give you day to day that golang doesn't? (Generics being the first obvious example, but I have to agree that there are a handful of use cases where they're useful)
- dthul 5y agoThe return types of fallible functions map naturally onto sum types. By using product types instead there is a semantic mismatch. You get an error and a value but only one of those is valid. So you need to follow certain code idioms to get back the sum type semantics whereas this is something the type system could handle for you. Go's reasoning for that might be that they didn't want to have the complexity of sum types in the language, which is fair but is a tradeoff.
- pkolaczk 5y agoA product type forces the language to have a special "invalid" state for every type like Nil, and this reminds me of all the problems related to null handling I know from java - like forgetting to check for null / Nil. A product type also allows returning weird states: no error and no value, or both error and value. I strongly believe that invalid states should be unrepresentable, rather than allowed by the type system and then fought by discipline and tooling.
- maccard 5y agoHonestly, I use go for things I wouldn't use c++ for even if I had the choice. Do I want to do some file wrangling, text manipulation, async or web api calls? Even the "nicest" of c++ libraries (manu of which are poor wrappers around a C library) are really poor ergonomically where go takes the biscuit. I definitely don't see myself writing gameplay code in go though
- raverbashing 5y agoI wanted to like Go but to be honest it really seems to be trying hard to be unlikeable. Rust has some weird corners, but it seems they're good at explaining things. Go tries to make some things easier (though, sure, still easier than C++) but they make it in a opaque or weird way. Some changes also seem to change too fast, but that might just be me looking from the outside
- magnio 5y agoThe talk at HOPL 4 by Bjarne: https://www.pldi21.org/prerecorded_hopl.5.html https://www.pldi21.org/prerecorded_hopl.5.html The whole event and conference is full of other interesting talks too: https://www.pldi21.org/track_hopl.html https://www.pldi21.org/track_hopl.html https://www.pldi21.org/home.html https://www.pldi21.org/home.html
- blippage 5y agoI used to be excited about learning new languages, but a few years ago I lost interest and decided to consolidate on just one language. That language was C++. C++ gets you most of the way to Python, which is as high as you can go (cue Smug Lisp Weenies with "muh macros"). So stop futzing around, and just use C++. All these other plethora of languages are all well and good, and I'm sure they all have their secret sauce, but is their secret sauce tasty enough to justify a switch? Unless a language consistently allows you to do in 1 line of code what others can do in 10, then there's little point to them. Having said that, I have recently been poking my nose into Ada for use in microcontrollers. Their notion of "tasks" seemed quite interesting. A version for AVR didn't really seem to be any better than C, just with a different syntax. The one for the Raspberry Pi Pico didn't support tasks, which took a lot off the shine about the prospect of switching to Ada for me. Maybe it's too early days for the Pico, though. I also had a quick try at Julia, as I was interested in trying out some DSP. There seemed to be some nice features about it. It seemed quite good at arrays. You can read a binary file very easily and convert it to a different type if required. So it is still on my radar. I use Python for quick-and-dirty stuff. Nevertheless, C++ is basically unbeatable generally.
- exdsq 5y agoI've considered doing this - I spend so much time learning new languages that I am average in many but not an expert in one. However, when I look at what language to pick for that 'one', I can't decide. It's gone from Python -> Common Lisp -> Rust, etc... What are some arguments for C++ to be The One?
- mdpye 5y agoThat it includes almost every possible feature ever posited in a language? /jk, sort of It's kind of a double edged sword...
- vnorilo 5y agoC++ has a great reach, from bare metal to very high level of abstraction. It can be squeezed to support almost any paradigm, oop to functional. You can make dynamic object systems, build a reflection system or a garbage collector. You can do compile time programming. In general, a systems language is a great asset in your toolbelt. A high level one can let you shape your own environment to great detail. In the end I think most systems languages will take you to a similar place. Many others have fewer footguns or better ergonomics than C++. Its distinctive feature/bug is having no opinion of almost anything. Or alternatively, you can find subcommunities with almost any opinion.
- Santosh83 5y agoDoes anyone know if Stroustrup has spoken in detail on Rust, the current most likely long-term replacement for C++?
- maccard 5y agoWhat makes you think that rust is a long term replacement for c++? I'm neither a rustacean or a dogmatic c++ follower, but it'd pretty clear to me right now that rust isn't going to replace C++. There is so much inertia in the field with both existing projects and new projects being written on C++, what seems more likely is you end up with a split akin to C vs C++
- secondcoming 5y agoThe success of Rust in industry depends on how it fares in the Linux kernel, IMO. C++ was never even considered for that. If I was a young dev learning a systems language for the first time, I'd most likely pick rust.
- deleted 5y ago[deleted]
- maccard 5y agoC++ isn't exclusively a systems level language either though, lets be clear. Assuming rust eats all the existing C code in the various kernels (MacOS, BSD, Linux, Windows), that wouldn't mean it's replaced C++ at all - it would have replaced C.
- pjmlp 5y agoYes, > He’s aware of other languages, as he reveals in his answer to a later question. (“I think C++ can do anything Rust can do, and I would like it to be much simpler to use.”) And towards the end, he couldn’t resist noting that longevity has its advantages. “It’s highly humorous when some of the Rust people come up and accuse me of having stolen some of their ideas without acknowledging — when some of the things I did I actually did almost 40 years ago.” Taken from https://thenewstack.io/c-creator-bjarne-stroustrup-weighs-in-on-distributed-systems-type-safety-and-rust/ https://thenewstack.io/c-creator-bjarne-stroustrup-weighs-in... > Pramod: Any newer languages like Rust or Go interests you? > > Bjarne: Yeah, I look at new languages roughly all the time. You learn something every time. It is interesting but as I said I’m more of a systems guy than the languages guys. I probably look less at languages than you’d think. I look at what I think is interesting, I try them out but what I really do is to look at what problems do my colleagues and students have and how do I solve them. Taken from https://mappingthejourney.com/single-post/2017/07/29/interview-with-bjarne-stroustrup-creator-of-c/ https://mappingthejourney.com/single-post/2017/07/29/intervi... As for Rust being a long term replacement for C++, just think how C++ dominates the Apple, Google, Microsoft, NVidia, AMD, Playstation, Switch, HPC, HPF, games middleware, LLVM and GCC ecosystems, and how after 40 years there are domains C++ has failed to take away from C despite being a much better and safer language. Rust and C++ will co-exist for many decades to come.
- mtzet 5y agoAt a 168 pages, I only had time to skim it, but this was much better than I thought it would be. He honestly addresses many of my complaints about C++. In the discussion of variant, optional and any: - He bemoans that "The possibility of direct language, as opposed to standard-library, support appears not to have been seriously considered" - He acknowledges that "variant and friends address an important problem, but inelegantly." - He considers variant, optional and any a "stop-gap measure" - In discussion of a pattern matching library he acknowledges the need for "both closed sets of alternatives (algebraic types) and open sets (class hierarchies)." and explicitly says the aim is to remove the visitor pattern (whereas c++17 just added std library syntax for it) In the modules discussion (9.3.1), he also identifies the problem that "[the hello world program] yields 419,909 characters for the compiler to digest". I wish he'd also address visiblity specifiers at a module level, rather than just at a class level. In the static reflection discussion (9.6.2), he discusses the typical problem of iterating over members of a struct. This is indeed a point where C++ has not really progressed much since ANSI C. The discussion of error handling in chapter 7 felt a bit lacking. My main problem with exceptions isn't performance, but that I can't determine if I've handled all error conditions. The idea of using exceptions for non-local errors and error codes for local errors is too vague. It also doesn't really make error codes much easier to use. For my money, I still think that using error codes and providing syntactic sugar for dealing with the common boilerplate is the best compromise. I can accept exception/panics when they are not supposed to be caught, but just cleanly terminate the application. Maybe C++ will solve these problems in the future (C++23? C++26?), maybe not. In the meantime, the new languages on the block are attractive because they solve these problems _today_.
- Negitivefrags 5y agoI find it surprising that anyone could imagine that the creator of C++ is unaware of its issues. I’m sure he appreciates them better than almost anyone else and would be the first to acknowledge them. But compromises have to be made to create a useful langague and path dependency means that sometimes the sub-optimal long term choice is still the right choice to make right now.
- mjburgess 5y ago
- thom 5y agoI recently wanted to get back into C++ but on closer inspection, found it so thoroughly modern than it didn't really tick the sentimental box I was looking for. So I starting writing C again, and it's been weirdly enjoyable. I still think if I were a young programmer somehow in the position of having to make a career bet on a single language, it'd be Rust. But I'd respect anyone who picked C++.
- germandiago 5y agoI have based my career on top of C++/backend/soft-real time systems. I still have to read the full paper, thanks for the post! Many people rant about C++, but, IMHO, overall, taking into account ecosystem, tools, etc. C++ stands as an almost unbeatable technology when you put everything together. The language has quirks, asymmetries and all of that. C++ lives the curse/blessing of C compatibility. But since C++11 it is nicer to use and all the standards after it have been improving on it: generic lambdas, move semantics, structured bindings, string non-template parameters, constexpr and consteval, decltype, auto, concepts... and now the C/C++ ISO committees seem to be more coordinated: seems they are proposing subsets like attributes, lambdas or nullptr into C, directly, and bool and others. It is amazing what you can do with C++ that is difficult or almost impossible to do with other languages, and you have basically all C interfaces available, which are the base of so many libraries since C is basically how you interface native code from almost everywhere. On the missing pieces I would mention that you need to use macros to have some kind of reflection for members and pattern matching and networking would be really nice to have. Also, resource embedding could be better (#embed and std::embed seem to be trying to solve this). Also, user-defined attributes for things such as struct MyType { [[serializable]] int myInt; ... } would be really nice and it works well in languages such as C#, Java and D. Modules are still an experiment implementation-wise, but hey, they will improve on the side of hiding implementation details by a big margin and have a lot of potential. As for the ecosystem, nowadays you have CMake (whose language sucks badly) and Meson (which I personally love). Together with Conan package management things have improved a lot since I started coding in around 2001. Pack that with an IDE like CLion or Visual Studio + Resharper or lightweight IDE (Emacs + Lsp and the like) and you have an environment that is very competitive and whose code can be compiled almost anywhere. From ARM to x86, MIPS and even Webassembly. That is why I think C++ is still the way to go if what you want is performance: you also have interfaces such as OpenCL/GL/Vulkan/SIMD libraries (though not C++ standard) where you can access hardware. Also, vendors and open source have things such as https://github.com/cginternals/glbinding https://github.com/cginternals/glbinding or https://github.com/KhronosGroup/Vulkan-Hpp https://github.com/KhronosGroup/Vulkan-Hpp which help quite a bit and always oriented towards C++. It seems that C++ is becoming the natural child of C for inheriting graphics programming and some of the embedded area, though C is still king there. Or look at https://github.com/VcDevel/std-simd https://github.com/VcDevel/std-simd to access SIMD. If you want GUIs, same, you have at least (but not only) Qt or WxWidgets. Want to interface scripting? Pybind11, Boost.Python, WrenBind17 for Wren, Sol2 for Lua... and all things that interface to C work also if you feel brave... I really think that when it is about getting the job done... C++ goes a long way towards the task. This is my 20 year experience of C++, almost 13 of those years professionally. Now, back to read the paper. :)
- locao 5y agoReading some comments here frustrates me out how a lot of people still put C and C++ in the same play field. 20 years ago, when you could consider C++ as a "C with classes" that was almost OK, but today they are way too different to consider them as the same thing. That said, personally, I am still comfortable and productive writing C code, but C++ has been a no-no since C++14. But that's just me and my point is: people should stop saying C and C++ are similar.
- ThePhysicist 5y agoI think I'd like C++ much more if it had a proper package manager. I know there's Conan and a few others but having an official way to install a library would be so great. I recently got back into game programming as a hobby and dusted off some of my old C++ projects from 2010, and while I was able to get them up and running again (which I guess speaks for C++ as well) it was pretty painful and involved downloading and installing several packages by hand. Using languages like Go, Python or Javascript feels much more seamless as you can just say "pip install ..." or "npm install" or "go get ./..." to install all your dependencies (there are pitfalls there as well).
- xscott 5y agoI've seen this complaint a lot, but I don't get it. For C++, the system package manager (yum, apt, pacman) seems sufficient to install most anything I've ever needed. Are you programming under Windows? My biggest complaints about C++ generally revolve around all the inconsistencies / special cases, and I believe these are mostly in the name of backwards compatibility. For any of the major compilers: - Integer literals are 32 bits, even on 64 bit platforms. You almost always want a ssize_t, but you get an int, and int is almost always 32 bits. (let's dodge the religious war about unsigned vs signed) - String literals are basically const char star pointers, but you should hold them in a string class. - Even the syntax for declaring a variable is a total mess. Depending on details about foo (initializer_list, POD type, explicit constructors, etc), there are a lot of special cases in the following: foo x; foo x(); foo x(1); foo x(1, 2); foo x{}; foo x{1}; foo x{1, 2}; foo x = {}; foo x = { 1 }; foo x = { 1, 2 }; foo x = foo(); foo x = foo(1); foo x = foo(1, 2); auto x = foo(); auto x = foo(1); ... For some of those, you can't even know what's really happening unless you know the specific implementation of the type/class. And as a special bit of trivia, one of those doesn't even declare a variable. - There are a lot of special cases and non-obvious idioms around declaring constructors and assignment operators. I think it's too much to remember all the rules, so most everyone is forced to find a subset of the language out of necessity.
- duped 5y ago> For C++, the system package manager (yum, apt, pacman) seems sufficient to install most anything I've ever needed The system package manager installs globally and prefers dynamic linking. This makes it generally impossible to distribute software reliably without packaging it for the system package manager being used. Dependencies should be local to the project and prefer static linking to avoid deployment/distribution errors.
- Koshkin 5y agoAt 36 now, C++ has aged extremely well. Perhaps not to everyone's taste, but it remains an exquisite, high-precision tool one could do anything with. Boost, a set of libraries, is a good testament to how much can be accomplished given just enough ability to create abstractions, and few languages can compare with C++ in that regard - especially taking into account runtime costs (C#, for example, heavily relies on reflection).
- thevibesman 5y agoJust started reading it, but I noticed that in the chronology, in 1979 for C with Classes “public/private” is listed. Was “protected” a later addition?
- nineteen999 5y agoThis document says that "the language was updated again in 1989 to include protected and static members, as well as inheritance from several classes." https://www.cplusplus.com/info/history/ https://www.cplusplus.com/info/history/
- xedrac 5y agoAs someone who has invested heavily in C++, and really likes the how modern C++ has evolved, I actually have a hard time imagining myself ever starting a new project in C++ again. It's not that I can't write very reliable code in modern C++, because I have and still do. It's just that the amount of effort involved in doing so is high compared to something like Rust. A lot of the cognitive load is shifted to the compiler. I've worked in so many existing C++ code bases where I had to spend my time tracking down bug after bug because the people that wrote it weren't very skilled at C++. Rust has its problems too (dependency tree bloat, slow compile times, steep learning curve, immaturity...), but one thing it does is makes all programmers much less likely to write bugs that aren't simply logic errors. And in a team, that's a HUGE win.