16 ms·
In Defense of C++
- lordleft 1y agoGreat article. Modern C++ has come a really long way. I think lots of people have no idea about the newer features of the standard library and how much they minimize footguns.
- sunshowers 1y agoLambdas, a modern C++ feature, can borrow from the stack and escape the stack. (This led to one of the more memorable bugs I've been part of debugging.) It's hard to take any claims about modern C++ seriously when the WG thought this was an acceptable feature to ship. Of course, the article doesn't mention lambdas.
- im3w1l 1y agoWhy wouldn't it be acceptable to ship? This is how everything works in C++. You always have to mind your references.
- sunshowers 1y agoExactly! This is my problem with the C++ community's culture. At no point is safety put first.
- Yoric 1y agoYeah, it's great that the C++ community starts to take safety in consideration, but one has to admit that safety always comes as the last priority, behind compatibility, convenience, performance and expressiveness.
- StillBored 1y agoIts worse. The day I discovered that std::array is explicitly not range/bounds checked by default I really wanted to write some angry letters to the committee members. Why go through all the trouble to make a better array, and require the user to call a special .at() function to get range checking rather than the other way around? I promptly went into my standard library and reversed that decision because if i'm going to the trouble to use a C++ array class, it better damn well give me a tiny bit of additional protection. The .at() call should have been the version that reverted to C array behavior without the bounds checking. And its these kinds of decisions repeated over and over. I get its a committee. Some of the decisions won't be the best, but by 2011 everyone had already been complaining about memory safety issues for 15+ years and there wasn't enough politics on the comittee to recognize that a big reason for using C++ over C was the ability of the language to protect some of the sharper edges of C?
- mbac32768 1y agoGood news! Contracts were approved for c++26 so they should be in compilers by like 2031 and then you can configure arrays and vectors to abort on out-of-bounds errors instead of corrupting your program. Let no one accuse the committee of being unresponsive.
- fluoridation 1y ago>Why go through all the trouble to make a better array, and require the user to call a special .at() function to get range checking rather than the other way around? Because the point was not to make an array type that's safe by default, but rather to make an array type that behaves like an object, and can be returned, copied, etc. I mean, I agree with you, I think operator[]() should range-check by default, but you're simply misunderstanding the rationale for the class.
- StillBored 1y agoWhich goes to the GP's point, which is that security and robustness are not on the radar. And my point in providing a concrete example, where a decision was made to prioritize unsafe behavior in a known problematic area, when they could just as well have made a half dozen other decisions which would have solved a long standing problem rather than just perpetuating it with some new syntactic sugar.
- fluoridation 1y agoI didn't dispute that, I was simply addressing the point about std::array. The class is not meant to be "arrays, but as good as they could possibly be". It's "arrays, but as first-class objects instead of weird language constructs". That said, making std::array::operator[]() range-checking would have been worse, because it would have been the only overload that did that. Could they have, in the same version, made all the overloads range-checking? Maybe, I don't know.
- TinkersW 1y agostd::array [] is checked if you have the appropriate build settings toggled, which of course you should during development. The same applies to many of the other baseless complaints I'm seeing here, learn to use your tools fools.
- BeetleB 1y agoThis is like writing an article entitled "In Defense of Guns", and then belittling the fact it can kill by saying "You always have to track your bullets".[1] [1] Not me making this up - I started getting into guns and this is what people say.
- im3w1l 1y agoTo me it's as if someone releases a new gun model and people single that gun out and complain that if you shoot someone with it they may die. Like it's a critique of guns as a concept not of that particular one. In a complete tangent I think that "smart guns" that only let you shoot bullseye targets, animals and designated un-persons are not far off.
- bluGill 1y agoThey can, but I find in practice that I never do this so it doesn't matter.
- sunshowers 1y agoI'm glad, but my problem is with the claim that modern C++ is safer. They added new features that are very easy to misuse. Meanwhile in Rust you can freely borrow from the stack in closures, and the borrow checker ensures that you'll not screw up. That's what (psychological) safety feels like.
- fluoridation 1y agoLambdas are syntactic sugar over functors, and it was possible all along to define a functor that stores a local address and then return it from the scope, thus leaving a dangling pointer. They don't introduce any new places for bugs to creep in, other than confusing programmers who are used to garbage-collected languages. That C++11 is safer than C++98 is still true, as this and other convenience features make it harder to introduce bugs from boilerplate code.
- sunshowers 1y agoThe ergonomics matter a lot. Of course a lambda is equivalent to a functor that stores a local reference, but making errors with lambdas requires disturbingly little friction. In any case, if you want safety and performance, use Rust.
- fluoridation 1y ago>making errors with lambdas requires disturbingly little friction Not any less than other parts of the language. If you capture by reference you need to mind your lifetimes. If you need something more dynamic then capture by copy and use pointers as needed. It unfortunate the developer who introduced that bug you mentioned didn't keep that in mind, but this is not a problem that lambdas introduced; it's been there all along. The exact same thing would've happened if they had stored a reference to a dynamic object in another dynamic object. If the latter lives longer than the former you get a dangling reference. >In any case, if you want safety and performance, use Rust. Personally, I prefer performance and stability. I've already had to fix broken dependencies multiple times after a new rustc version was released. Wake me up when the language is done evolving on a monthly basis.
- TuxSH 1y agoCapturing lambdas are no different from handwritten structures with operator() ("functors"), therefore it makes no sense castrating them. Borrowing from stack is super useful when your lambda also lives in the stack; stack escaping is a problem, but it can be made harder by having templates take Fn& instead of const Fn& or Fn&&; that or just a plain function pointer.
- loeg 1y agoConvenience is a difference in kind. Like, I'm not god's gift to programming or anything, but I'm decently good at it, and I wrote a use-after-return bug due to a lambda reference last week.
- sunshowers 1y agoBorrowing from the stack is definitely useful. I do it all the time, safely (truly safely), in Rust.
- account42 1y agoNot an issue if you make use of the tools available: https://godbolt.org/z/xW14hGeoj https://godbolt.org/z/xW14hGeoj
- sunshowers 1y agoIt looks like (a) this is a warning, not an error (why? the code is always wrong) and (b) the warning was added in clang 21 which came out this year. I also suspect that it wouldn't be able to detect complex cases that require interprocedural analysis. The bug I saw happened a few years ago, and convinced me to switch to Rust where it simply cannot happen.
- 1718627440 1y agoA warning in C, C++ is the compiler saying "this is terribly broken, won't do what you want and I will exploit this". As opposed to an error, which means "I don't even know what you mean". Taking warnings lightly isn't the way to go in C or C++.
- Symmetry 1y agoI eagerly await the day when they do away with the distinction between ".cpp" and ".hpp" files and the textual substitution nature of "#include" and replace them all with a proper module system.
- 1718627440 1y agoThe distinction between *.cpp and *.hpp is purely convention, the compiler does not care at all.
- alextingle 1y agoModules are a disaster. It's hard enough to get programmers to care enough about how their code affects build times. Modules make it impossible for them to care, and will lead to horrible problems when building large projects.
- beej71 1y agoIt doesn't mention the horrific template error messages. I'd heard that this was an area targeted for improvement a while ago... Is it better these days?
- jandrewrogers 1y agoQualitatively better. C++20 'concepts' obviated the need for the arcane metaprogramming tricks responsible for generating the vast majority of that template vomit. Now you mostly get an error to the effect of "constraint foo not satisfied by type bar" at the point of use that tells you specifically what needs to change about the type or value to satisfy the compiler.
- einpoklum 1y ago> C++20 'concepts' obviated the need for the arcane metaprogramming tricks responsible for generating the vast majority of that template vomit. 1. Somewhat exaggerated claim. It reduced that need; and for when you can assumpe everyting is C++20 or later. 2. Even to the extent the need for TMP was obviated in principle - it will take decades for TMP to go away in popular libraries and in people's application code. At that time, maybe, we would stoopp seeing these endless compliation artifacts.
- deleted 1y ago[deleted]
- franky47 1y agoWhat’s a good (ie: opinionated) code formatter and unit test framework for C++ these days? I just had a PR on an old C++ project, and spending 8 years in the web ecosystem have raised the bar around tooling expectations. Rust is particularly sweet to work with in that regard.
- jonstewart 1y agoCatch2 is great as a unit test framework. Running unit tests with the address sanitizer and UB sanitizer enabled go a long way towards addressing most memory safety bugs. The kind of C++ you write then is a far cry from what the haters complain about with bad old VC6 era C++.
- einpoklum 1y ago> Catch2 is great as a unit test framework. It's "great" mainly in the sense of being very large, and making your code very lage - and slow to build. I would not recommend it unless you absolutely must have some particular feature not existing elsewhere. Here's a long list of C++ unit testing frameworks: https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C++ https://en.wikipedia.org/wiki/List_of_unit_testing_framework... And you might consider: * doctest: https://github.com/doctest/doctest https://github.com/doctest/doctest * snitch: https://github.com/snitch-org/snitch https://github.com/snitch-org/snitch * ut/micro-test: https://github.com/boost-ext/ut https://github.com/boost-ext/ut
- jonstewart 1y agoI guess I consider it great in comparison to CppUnit, Boost Test, and Google Test. I also like that it incorporated nonius, that's a big win.
- lang4d 1y agoMy go to for formatting would be clang-format, and for testing gtest. For more extensive formatting (that involves the compiler) clang-tidy goes a long way
- fithisux 1y ago"Rust shines in new projects where safety is the priority, while C++ continues to dominate legacy systems and performance-critical domains." the truth
- MBCook 1y agoHasn’t Rust been shown to be very fast, especially since it can elide a lot of safety checks that would otherwise be necessary to prevent bugs? On legacy code bases, sure. C++ rules in legacy C++ codebases. That’s kind of a given isn’t it? So that’s not a benefit. Just a fact.
- charlieflowers 1y ago> "while C++ continues to dominate ... performance-critical domains" Why performance-critical domains? Does C++ have a performance edge over Rust?
- fithisux 1y agoThat is what the article says.
- charlieflowers 1y agoIt seems you agree? I'd love to hear your thoughts on it. I had gotten the impression (second-hand) that they were roughly equally matched in this regard.
- tialaramex 1y agoBut you stated it was "the truth" and so we might reasonably wonder why you think so, unless it's that you just believe anything you read. "ABI: Now or never" by Titus Winters addresses some perf leaks C++ had years ago, which it can't fix (if it retains its ABI promise). They're not big but they accumulate over time and the whole point of that document was to explain what the price is if (unlike Rust) you refuse to take steps to address it. Rust has some places where it can't match C++ perf, but unlike that previous set Rust isn't obliged to keep one hand tied behind its back. So this gently tips the scales further towards Rust over time. Worse, attempts to improve C++ safety often make its performance worse. There is no equivalent activity in Rust, they already have safety. So these can heap more perf woes on a C++ codebase over time.
- AHTERIX5000 1y agoI write C++ daily and I really can't take seriously arguments how C++ is safe if you know what you're doing like come on. Any sufficiently large and complex codebases tend to have bugs and footguns and using tools like memory safe languages limit blast radius considerably. Smart pointers are neat but they are not a solution for memory safety. Just using standard containers and iterators can lead to lots of footguns, or utils like string_view.
- fouronnes3 1y agoThis is a good article but it only scratches the surface, as is always the case when it comes to C++. When I made a meme about C++ [1] I was purposeful in choosing the iceberg format. To me it's not quite satisfying to say that C++ is merely complex or vast. A more fitting word would be "arcane", "monumental" or "titanic" (get it?). There's a specific feeling you get when you're trying to understand what the hell is an xvalue, why std::move doesn't move or why std::remove doesn't remove. The Forest Gump C++ is another meme that captures this feeling very well (not by me) [2]. What it comes down to is developer experience (DX), and C++ has a terrible one. Down to syntax and all the way up to package management a C++ developper feels stuck to a time before they were born. At least we have a lot of time to think about all that while our code compiles. But that might just be the price for all the power it gives you. [1] https://victorpoughon.github.io/cppiceberg/ https://victorpoughon.github.io/cppiceberg/ [2] https://mikelui.io/img/c++_init_forest.gif https://mikelui.io/img/c++_init_forest.gif
- jandrese 1y agoIn Linuxland you at least have pkg-config to help with package management. It's not perfect but neither is any other package management solution. If I'm writing a small utility or something the Makefile typically looks something like this: CC=clang PACKAGES=libcurl libturbojpeg CFLAGS=-Wall -pedantic --std=gnu17 -g $(shell pkg-config --cflags $(PACKAGES)) LDLIBS=$(shell pkg-config --libs $(PACKAGES)) ALL: imagerunner imagerunner: imagerunner.o image_decoder.o downloader.o
- duped 1y agoConsider that to do this you must: - Use a build system like make, you can't just `c++ build` - Understand that C++ compilers by default have no idea where most things are, you have to tell them exactly where to search - Use an external tool that's not your build system or compiler to actually inform the compiler what those search paths are - Oh also understand the compiler doesn't actually output what you want, you also need a linker - That linker also doesn't know where to find things, so you need the external tool to use it - Oh and you still have to use a package manager to install those dependencies to work with pkg-config, and it will install them globally. If you want to use it in different projects you better hope you're ok with them all sharing the same version. Now you can see why things like IDEs became default tools for teaching students how to write C and C++, because there's no "open a text editor and then `c++ build file.cpp` to get output" for anything except hello world examples.
- EGreg 1y agoPython’s “there should be one obvious way to do it” slogan often collides with reality these days too, since the language sprawled into multiple idioms just like C++: for printing you can use print("hi"), f-strings like f"hi {x}", .format(), % formatting, or concatenation with +; for loops you can iterate with for i in range(n), list comprehensions [f(i) for i in seq], generator expressions (f(i) for i in seq), or map/filter/lambda; unpacking can be done with a,b=pair, tuple() casting, slicing, *args capture, or dictionary unpacking with *; conditionals can be written with if/else blocks, one-line ternary x if cond else y, and/or short-circuit hacks, or pattern matching match/case; default values can come from dict.get(k,default), x or default, try/except, or setdefault; swapping variables can be done with a,b=b,a, with a temp var, with tuple packing/unpacking, or with simultaneous assignment; joining strings can be done with "".join(list), concatenation in a loop, reduce(operator.add, seq), or f-strings; reading files can be open().read(), iterating line by line with for line in f, using pathlib.Path.read_text(), or with open(...) as f; building lists can be done with append in a loop, comprehensions, list(map(...)), or unpacking with [*a,*b]; dictionaries can be merged with {*a,*b}, a|b (Python 3.9+), dict(a,*b), update(), or comprehensions; equality and membership checks can be ==, is, in, any(...), all(...), or chained comparisons; function arguments can be passed positionally, by name, unpacked with * and \*, or using functools.partial; iteration with indexes can be for i in range(len(seq)), for i,x in enumerate(seq), zip(range(n),seq), or itertools; multiple return values can be tuples, lists, dicts, namedtuples, dataclasses, or objects; even truthiness tests can be if x:, if bool(x):, if len(x):, or if x != []:. Whew!
- lyu07282 1y agoBut hey at least python forces you to use whitespace properly hinthinthint
- jasperry 1y agoThe author argues that if rewriting a C++ codebase in Rust makes it more memory-safe, that's not because Rust is memory-safe. What?
- Night_Thastus 1y agoDid you read what they wrote? Their point is that doing a fresh rewrite of old code in any language will often inherently fix some old issues - including memory safety ones. Because it's a re-write, you already know all the requirements. You know what works and what doesn't. You know what kind of data should be laid out and how to do it. Because of that, a fresh re-write will often erase bugs (including memory ones) that were present originally.
- puzzledobserver 1y agoThat claim appears to contradict the second-system effect [0]. The observation is that second implementation of a successful system is often much less successful, overengineered, and bloated, due to programmer overconfidence. On the other hand, I am unsure of how frequently the second-system effect occurs or the scenarios in which it occurs either. Perhaps it is less of a concern when disciplined developers are simply doing rewrites, rather than feature additions. I don't know. [0] https://en.wikipedia.org/wiki/Second-system_effect https://en.wikipedia.org/wiki/Second-system_effect
- Night_Thastus 1y agoI won't say the second-system effect doesn't exist, but I wouldn't say it applies every single time either. There's too many variables. Sometimes a rewrite is just a rewrite. Sometimes the level of bloat or feature-creep is tiny. Sometimes the old code was so bad that the rewrite fully offsets any bloat.
- AnimalMuppet 1y agoThe second system effect isn't that a rewrite necessarily has more bugs/problems. The second system effect is that a follow-on project with all of everybody's dreamed-of bells and whistles that everybody in marketing wants is going to have more problems/bugs, and may not even be finishable at all.
- nzeid 1y ago> Just using Rust will not magically make your application safe; it will just make it a lot harder to have memory leaks or safety issues. You know, not sure I even agree with the memory leaks part. If you define a memory leak very narrowly as forgetting to free a pointer, this is correct. But in my experience working with many languages including C/C++, forgotten pointers are almost never the problem. You're gonna be dealing with issues involving "peaky" memory usage e.g. erroneously persistent references to objects or bursty memory allocation patterns. And these occur in all languages.
- andrewmcwatters 1y agoWhat's worse in languages like Go, which I love, is that you won't even immediately how to solve this unless you have experience dropping down into doing things you just would have normally done in C or C++. Even the Go authors themselves on Go's website display a process of debugging memory usage that looks identical to a workflow you would have done in C++. So, like, what's the point? Just use C++. I really do think Go is nice, but at this point I would relegate it to the workplace where I know I am working with a highly variable team of developers who in almost all cases will have a very poor background in debugging anything meaningful at all.
- AlotOfReading 1y agoC++'s design encourages that kind of allocation "leak" though. The article suggests using smart pointers, so let's take an example from there and mix make_shared with weak_ptr. Congrats, you've now extended the lifetime of the allocation to whatever the lifetime of your weak pointer is. Rc::Weak does the same thing in Rust, but I rarely see anyone use it.
- fluoridation 1y agoHuh? What do you mean? The point of std::weak_ptr is that it's non-owning, so it has no effect on the lifetime of the pointed object.
- deschutes 1y ago
- scj 1y ago"you can write perfectly fine code without ever needing to worry about the more complex features of the language. You can write simple, readable, and maintainable code in C++ without ever needing to use templates, operator overloading, or any of the other more advanced features of the language." You could also inherit a massive codebase old enough to need a prostate exam that was written by many people who wanted to prove just how much of the language spec they could use. If selecting a job mostly under the Veil of Ignorance, I'll take a large legacy C project over C++ any day.
- whobre 1y ago> C++ is very old, in fact, it came out in 1985, to put it into perspective, that’s 4 years before the first version of Windows was released Nitpick, I guess, but Windows 1.0 was released in November 1985: https://en.m.wikipedia.org/wiki/Windows_1.0 https://en.m.wikipedia.org/wiki/Windows_1.0
- justicehunter 1y agoI'm not sure what I feel about the article's point on boost. It does contribute a lot to the standard library and does provide some excellent libraries, like boost.Unordered
- Night_Thastus 1y agoBoost is an awful whole with a couple very nice tiny parts inside. If you can restrict to using the 'good' parts than it can be OK, but it's pulling in a huge dependency for very little gain these days.
- thelittlenag 1y agoI'm old enough to recall when boost first came out, and when it matured into a very nice library. What's happened in the last 15 years that boost is no longer something I would want to reach for?
- Night_Thastus 1y agoC++11 through 17 negated a lot of its usefulness - the standard library does a lot of what Boost originally offered. Alternative libraries like QT are more coherent and better thought out.
- fluoridation 1y agoQt is... fine... as long as you're willing to commit and use only Qt instead of the standard library. It's from before the STL came out, so the two don't mesh together really at all.
- Night_Thastus 1y agoIn my experience I've had no issues. Occasionally have to use things like toStdString() but otherwise I use a mix of std and qt, and haven't had any problems.
- g42gregory 1y agoI am not sure C++ needs a defense. Especially after C++ 11 cleanup.
- IshKebab 1y agoTerrible article. > you can write perfectly fine code without ever needing to worry about the more complex features of the language Not really because of undefined behaviour. You must be aware of and vigilant about the complexities of C++ because the compiler will not tell you when you get it wrong. I would argue that Rust is at least in the same complexity league as C++. But it doesn't matter because you don't need to remember that complexity to write code that works properly (almost all of the time anyway, there are some footguns in async Rust but it's nothing on C++). > Now is [improved safety in Rust rewrites] because of Rust? I’d argue in some small part, yes. However, I think the biggest factor is that any rewrite of an existing codebase is going to yield better results than the original codebase. A factor, sure. The biggest? Doubtful. It isn't only Rust's safety that helps here, it's its excellent type system. > But here’s the thing: all programming languages are unsafe if you don’t know what you’re doing. Somehow managed to fit two fallacies in one sentence! 1. The fallacy of the grey - no language is perfect therefore they are all the same. 2. "I don't make mistakes." > Just using Rust will not magically make your application safe; it will just make it a lot harder to have memory leaks or safety issues. Not true. As I said already Rust's very strong type system helps to make applications less buggy even ignoring memory safety bugs. > Yes, C++ can be made safer; in fact, it can even be made memory safe. There are a number of libraries and tools available that can help make C++ code safer, such as smart pointers, static analysis tools, and memory sanitizers lol > Avoid boost like the plague. Cool, so the ecosystem isn't confusing but you have to avoid one of the most popular libraries. And Boost is fine anyway. It has lots of quite high quality libraries, even if they do love templates too much. > Unless you are writing a large and complex application that requires the specific features provided by Boost, you are better off using other libraries that are more modern and easier to use. Uhuh what would you recommend instead of Boost ICL? I guess it's a valiant attempt but this is basically "in defense of penny farthings" when the safety bicycle was invented.
- MBCook 1y ago> Just using Rust will not magically make your application safe; it will just make it a lot harder to have memory leaks or safety issues. Even if we take this claim at face value, isn’t that great? Memory safety is a HUGE source of bugs and security issues. So the author is hand-waving away a really really good reason to use Rust (or other memory safe by default language). Overall I agree this seems a lot like “I like C++and I’m good at it so it’s fine” with justifications created from there.
- Night_Thastus 1y agoWhen it comes to programming, I generally decide my thoughts based on pain-in-my-ass levels. If I constantly have to fiddle with something to get it working, if it's fragile, if it frequently becomes a pain point - then it's not great. And out of all the tools and architecture I work with, C++ has been some of the least problematic. The STL is well-formed and easy to work with, creating user-defined types is easy, it's fast, and generally it has few issues when deploying. If there's something I need, there's a very high chance a C or C++ library exists to do what I need. Even crossing multiple major compiler versions doesn't seem to break anything, with rare exceptions. The biggest problem I have with C++ is how easy it is to get very long compile times, and how hard it feels like it is to analyze and fix that on a 'macro' (whole project) level. I waste ungodly amounts of time compiling. I swear I'm going to be on deaths door and see GCC running as my life flashes by. Some others that have been not-so-nice: * Python - Slow enough to be a bottleneck semi-frequently, hard to debug especially in a cross-language environment, frequently has library/deployment/initialization problems, and I find it generally hard to read because of the lack of types, significant whitespace, and that I can't easily jump with an IDE to see who owns what data. Also pip is demon spawn. I never want to see another Wheel error until the day I die. * VSC's IntelliSense - My god IntelliSense is picky. Having to manually specify every goddamn macro, one at a time in two different locations just to get it to stop breaking down is a nightmare. I wish it were more tolerant of having incomplete information, instead of just shutting down completely. * Fortran - It could just be me, but IDEs struggle with it. If you have any global data it may as well not exist as far as the IDE is concerned, which makes dealing with such projects very hard. * CMake - I'm amazed it works at all. It looks great for simple toy projects and has the power to handle larger projects, but it seems to quickly become an ungodly mess of strange comments and rules that aren't spelled out - and you have no way of stepping into it and seeing what it's doing. I try to touch it as infrequently as possible. It feels like C macros, in a bad way.
- bluGill 1y agoCMake is not a great language, but great effort has been put into cleaning up how things should be done. However you can't just upgrade, someone needs to go through the effort of using all that new stuff. In almost all projects the build system is an after thought that developers touch as little as possible to make things work and so it builds cruft constantly. You can do much better in CMake if you put some effort into cleaning it up - I have little hope anyone will do this though. We have a hard time getting developers to clean up messes in production code and that gets a lot more care and love.
- gmueckl 1y agoC++ will always stay relevant. Software has eaten the world. That transition is almost complete now. The languages that were around when it happened will stay deeply embedded in our fundamental tech stacks for another couple decades at least, if not centuries. And C and C++ are the lion's share of that. COBOL sticks around 66 years after its first release. Fortran is 68 years old and is still enormously relevant. Much, much more software was written in newer languages and has become so complex that replacements have become practically impossible (Fuchsia hasn't replaces Linux in Google products, wayland isn't ready to replace X11 etc)
- ktpsns 1y agoAs long as people write software (no pun intended), software will follow trends. For instance, in many scientific ecosystems, Matlab was successfully replaced by Scipy. Which happens to get replaced by Julia. Things don't neccessarily have to stay the same. Interestingly, such a generational trend currently happens with Rust, despite there has been numerous other popular languages such as D or Zig which didn't have the same traction. Sure, there are still Fortran codes. But I can hardly imagine that Fortran still plays a big role in another 68 years from now on.
- vhcr 1y agoScipy is a wrapper of Numpy, which is a wrapper of C and Fortran.
- gmueckl 1y agoI am not saying that these languages will stay around forever, mind you. But we have solidified the tech stacks involving these languages by making them ridiculously complex. Replacement of a programming language in one of the core components can only come through gradual and glacially slow evolution at this point. "Rewrite it in XYZ" as a clean slate approach on a big scale is simply a pipe dream. Re Matlab: I still see it thriving in the industry, for better or worse. Many engineers just seem to love it. I haven't seen many users of Julia yet. Where do you see those? I think that Julia deserves a fair chance, but it just doesn't have a presence in the fields I work in.
- pie_flavor 1y agoI don't think there could be any purer of an expression of the Blub Paradox. > Just use whatever parts of the language you like without worrying about what's most performant! It's not about performant. It's about understanding someone else's code six months after they've been fired, and thus restricting what they can possibly have done. And about not being pervasively unsafe. > "I don’t think C++ is outdated by any stretch of the imagination", "matter of personal taste". Except of course for header files, forward declarations, Make, the true hell of C++ dependency management (there's an explicit exhortation not to use libraries near the bottom), a thousand little things like string literals actually being byte pointers no matter how thoroughly they're almost compatible with std::string, etc. And of course the pervasive unsafety. Yes, it sure was last updated in 2023, the number of ways of doing the same thing has been expanded from four to five but the module system still doesn't work. > You can write unsafe code in Python! Rewriting always makes the code more safe whether it's in Rust or not! No. Nobody who has actually used Rust can reasonably arrive at this opinion. You can write C++ code that is sound; Rust-fluent people often do. The design does not come naturally just because of the process of rewriting, this is an entirely ridiculous thing to claim. You will make the same sorts of mistakes you made writing it fresh, because you are doing the same thing as you were when writing it fresh. The Rust compiler tells you things you were not thinking of, and Rust-fluent people write sound C++ code because they have long since internalized these rules. And the crack about Python is just stupid. When people say 'unsafe' and Rust in the same sentence, they are obviously talking about UB, which is a class of problem a cut above other kinds of bugs in its pervasiveness, exploitability, and ability to remain hidden from code review. It's 'just' memory safety that you're controlling, which according to Microsoft is 70% of all security related bugs. 70% is a lot! (plus thread safety, if this was not mentioned you know they have not bothered using Rust) In fact the entire narrative of 'you'll get it better the second time' is nonsense, the software being rewritten was usually written for the first time by totally different people, and the rewriters weren't around for it or most of the bugfixes. They're all starting fresh, the development process is nearly the same as the original blank slate was - if they get it right with Rust, then Rust is an active ingredient in getting it right! > Just use smart pointers! Yes, let me spam angle brackets on every single last function. 'Write it the way you want to write it' is the first point in the article, and here is the exact 'write it this way' that was critiquing. And you realistically won't do it on every function so it is just a matter of time until one of the functions you use regular references with creates a problem.
- scuff3d 1y agoA lot of this article boils down to "C++ is great... If you don't use most of the language"
- justinhj 1y agoNot a terrible thing on its face
- IncreasePosts 1y agoI think, if one of the most prominent C++ experts in the world(herb sutter), who chaired the C++ standards committee for 20+ years, who has evangelized the language for even longer than that - decides that complexity in the language has gotten out of control and sits down to write a simpler and safer dialect, then that is indicative of a problem with the language. My viewpoint on the language is that there are certain types of engineers who thrive in the complexity that is easy to arrive at in a C++ code base. These engineers are undoubtedly very smart, but, I think, lack a sense of aesthetics that I can never get past. Basically, the r/atbge of programming languages (Awful Taste But Great Execution).
- MontagFTB 1y agoWhen NIST released its summary judgement against C++ and other languages it deemed memory unsafe, the problem became less technical and more about politics and perception. If you're looking to work within two arms' length of the US Government, you have to consider the "written in C++" label seriously, regardless of how correct the code may be.
- Jtsummers 1y agoThe government is still happily commissioning new software projects that use C++. That may change in a few years, and some organizations may already be treating C++ more critically, but so far it's been unimpactful.
- jandrewrogers 1y agoNothing is going to happen for the foreseeable future, at least in the parts of government I tend to work with. It doesn't even come up in discussions of critical high-reliability system. They are still quite happy to buy and use C++, so I expect that is what they will be getting.
- gpderetta 1y agoAt some point the US government required ADA for all new development. Yet here we are.
- Jtsummers 1y agoADA is still the law, but, yes, Ada the language was mandated for 5 or 6 years and everyone got waivers for it anyways. A big difference between the Ada mandate and this current push is that the current effort is not to go to one language, but to a different category of languages (specifically, "memory safe" or ones with stronger guarantees of memory safety). That leaves it much more open than the Ada mandate did. This would be much more palatable for contractors compared to the previous mandate.
- rs186 1y agoIs there anything new here? Aren't these the same talking points people have been making for the past few years?
- loeg 1y ago> in C++, you can write perfectly fine code without ever needing to worry about the more complex features of the language. You can write simple, readable, and maintainable code in C++ without ever needing to use templates, operator overloading, or any of the other more advanced features of the language. This... doesn't really hold water. You have to learn about what the insane move semantics are (and the syntax for move ctors/operators) to do fairly basic things with the language. Overloaded operators like operator*() and operator<<() are widely used in the standard library so you're forced to understand what craziness they're doing under the hood. Basic standard library datatypes like std::vector use templates, so you're debugging template instantiation issues whether you write your own templated code or not.
- butterisgood 1y agoOverloaded operators were a terrible mistake in every programming language I've encountered them in. (Yes, sorry Haskell, you too!) I don't think move semantics are really that bad personally, and some languages move by default (isn't that Rust's whole thing?). What I don't like is the implicit ambiguous nature of "What does this line of code mean out of context" in C++. Good luck! I have hope for C++front/Cpp2. https://github.com/hsutter/cppfront https://github.com/hsutter/cppfront (oh and I think you can write a whole book on the different ways to initialize variables in C++). The result is you might be able to use C++ to write something new, and stick to a style that's readable... to you! But it might not make everyone else who "knows C++" instantly able to work on your code.
- loeg 1y ago> I don't think move semantics are really that bad personally, and some languages move by default (isn't that Rust's whole thing?). Rust's move semantics are good! C++'s have a lot of non-obvious footguns. > (oh and I think you can write a whole book on the different ways to initialize variables in C++). Yeah. Default init vs value init, etc. Lots of footguns.
- jandrewrogers 1y agoA benefit of operator overloads is that you can design drop-in replacements for primitive types to which those operators apply but with stronger safety guarantees e.g. fully defining their behavior instead of leaving it up to the compiler. This wasn't possible when they were added to the language and wasn't really transparent until C++17 or so but it has grown to be a useful safety feature.
- WCSTombs 1y agoGood article overall. There's one part I don't really agree with: > Here’s a rule of thumb I like to follow for C++: make it look as much like C as you possibly can, and avoid using too many advanced features of the language unless you really need to. This has me scratching my head a bit. In spite of C++ being nearly a superset of C, they are very different languages, and idiomatic C++ doesn't look very much like C. In fact, I'd argue that most of the stuff C++ adds to C allows you to write code that's much cleaner than the equivalent C code, if you use it the intended way. The one big exception I can think of is template metaprogramming, since the template code can be confusing, but if done well, the downstream code can be incredibly clean. There's an even bigger problem with this recommendation, which is how it relates to something else talked about in the article, namely "safety." I agree with the author that modern C++ can be a safe language, with programmer discipline. C++ offers a very good discipline to avoid resource leaks of all kinds (not just memory leaks), called RAII [1]. The problem here is that C++ code that leverages RAII looks nothing like C. Stepping back a bit, I feel there may be a more fundamental fallacy in this "C++ is Hard to Read" section in that the author seems to be saying that C++ can be hard to read for people who don't know the language well, and that this is a problem that should be addressed. This could be a little controversial, but in my opinion you shouldn't target your code to the level of programmers who don't know the language well. I think that's ultimately neither good for the code nor good for other programmers. I'm definitely not an expert on all the corners of C++, but I wouldn't avoid features I am familiar with just because other programmers might not be. [1] https://en.cppreference.com/w/cpp/language/raii.html https://en.cppreference.com/w/cpp/language/raii.html
- butterisgood 1y agoA pet peeve of mine is when people claim C++ is a superset of C. It really isn't. There's a lot of little nuanced differences that can bite you. Ignore the fact that having more keywords in C++ precludes the legality of some C code being C++. (`int class;`) void * implicit casting in C just works, but in C++ it must be an explicit cast (which is kind of funny considering all the confusing implicit behavior in C++). C++20 does have C11's designated initialization now, which helps in some cases, but that was a pain for a long time. enums and conversion between integers is very strict in C++. `char * message = "Hello"` is valid C but not C++ (since you cannot mutate the pointed to string, it must be `const` in C++) C99 introduced variadic macros that didn't become standard C++ until 2011. C doesn't allow for empty structs. You can do it in C++, but sizeof(EmptyStruct) is 1. And if C lets you get away with it in some compilers, I'll bet it's 0. Anyway, all of these things and likely more can ruin your party if you think you're going to compile C code with a C++ compiler. Also don't forget if you want code to be C callable in C++ you have to use `extern "C"` wrappers.
- jandrewrogers 1y ago> You can do it in C++, but sizeof(EmptyStruct) is 1. Unless you use the C++20 [[no_unique_address]] attribute, in which case it is 0 (if used correctly).
- butterisgood 1y agoI completely forgot about that!
- aw1621107 1y ago> C++20 does have C11's designated initialization now, which helps in some cases, but that was a pain for a long time. C++ designated initializers are slightly different in that the initialization order must match the declared member order. That is not required in C.
- o11c 1y agoIt also completely negates their utility, even though the exact "problem" they always bring up is already solved when you use normal constructors.
- BeetleB 1y ago> Here’s a rule of thumb I like to follow for C++: make it look as much like C as you possibly can, and avoid using too many advanced features of the language unless you really need to. Also, avoid using C++ classes while you're at it. I recently had to go back to writing C++ professionally after a many-year hiatus. We code in C++23, and I got a book to refresh me on the basics as well as all the new features. And man, doing OO in C++ just plain sucks. Needing to know things like copy and swap, and the Rule of Three/Five/Zero. Unless you're doing trivial things with classes, you'll need to know these things. If you don't need to know those things, you might as well stick to structs. Now I'll grant C++23 is much nicer than C++03 (just import std!) I was so happy to hear about optional, only to find out how fairly useless it is compared to pretty much every language that has implemented a "Maybe" type. Why add the feature if the compiler is not going to protect you from dereferencing without checking?
- butterisgood 1y agoI really don't like Object Oriented programming anywhere. Maybe Smalltalk had it right, but I've not messed with Pharo or anything else enough to get a feel for it. CLOS seems pretty good, but then again I'm a bit inexperienced. Bring back Dylan!
- fluoridation 1y agostd::optional does have dereference checking, but it's a run-time check: std::optional<T>::value(). Of course, you'll get an exception if the optional is empty, because there's nothing else for the callee to do.
- kronicum2025 1y agoThe safety part in this article is incorrect. There's a google doc somewhere where Google did an internal experiment and determined that safety c annot be achieved in C++ without an owning reference (essentially what Rust has).
- Attrecomet 1y agoAm I missing anything in the article about this problem in particular? Owning references are a part of modern C++, which should be covered by the author's arguments.
- aw1621107 1y ago> Owning references are a part of modern C++ Maybe we're thinking of different things, but I don't think C++ has owning references, modern or not? There's regular references (&) which are definitely not owning, and owning pointers (unique_ptr and friends), but neither of those quite match Rust's &.
- Attrecomet 1y agoAh, okay, that is a good point. I was not aware of that subtle difference, and replaced "owning reference" with "owning pointer" in my mind.
- steveklabnik 1y agoI think your parent may be slightly confused, in the sense of terminology: "owning reference" is a contradiction in Rust terms. Here's the document I believe your parent is referring to: https://docs.google.com/document/d/e/2PACX-1vSt2VB1zQAJ6JDMaIA9PlmEgBxz2K5Tx6w2JqJNeYCy0gU4aoubdTxlENSKNSrQ2TXqPWcuwtXe6PlO/pub https://docs.google.com/document/d/e/2PACX-1vSt2VB1zQAJ6JDMa... The claim in the article: > Yes, C++ can be made safer; in fact, it can even be made memory safe. The claim from this document: > We attempted to represent ownership and borrowing through the C++ type system, however the language does not lend itself to this. Thus memory safety in C++ would need to be achieved through runtime checks. It doesn't use "owning reference" anywhere.
- Animats 1y agoSo Boost is dying off? Good to know.
- e-dant 1y agoIf there are as many typos in some code as are in the article, there would be a whole lot of segfaults, too
- tsunagatta 1y ago> You can write simple and readable code in C++ if you want to. You can also write complex and unreadable code in C++ if you want to. It’s all about personal or team preference. Problem is, if you’re using C++ for anything serious, like the aforementioned game development, you will almost certainly have to use the existing libraries; so you’re forced to match whatever coding style they chose to use for their codebase. And in the case of Unreal, the advice “stick to the STL” also has to be thrown out since Unreal doesn’t use the STL at all. If you could use vanilla, by-the-books C++ all the time, it’d be fine, but I feel like that’s quite rare in practice.
- deleted 1y ago[deleted]
- camkego 1y agoThe article says "I think the biggest factor is that any rewrite of an existing codebase is going to yield better results than the original codebase.". Yeah, sorry, but no, ask some long-term developers about how this often goes.
- ryao 1y agoIt depends on the codebase. If the code base deserves to be a case study in how not to do programming, then a rewrite will definitely yield better results. I once encountered this situation with C# code written by an undergraduate, rewrote it from scratch in C++ and got a better result. In hindsight, the result would have been even better in C since I spent about 80% of my time fighting with C++ to try to use every language feature possible. I had just graduated from college and my code whole better, did a number of things wrong too (although far fewer to my credit). I look back at it in hindsight and think less is more when it comes to language features. I actually am currently maintaining that codebase at a health care startup (I left shortly after it was founded and rejoined not that long ago). I am incrementally rewriting it to use a C subset of C++ whenever I need to make a change to it. At some point, I expect to compile it as C and put C++ behind me.
- glouwbug 1y agoData structures like maps and vectors from the standard library are still incredibly useful and make a fantastic addition to C if your focus relies on POD types, though if real time performance with heap cohesion is a problem then you’re right to go pure C
- dayvster 1y agoHi author of the article here. I've been a software developer for nearly 2 decades at this point, contributed to several rewrites and oversaw several rewrites of legacy software. From my experience I can assure you that rewriting a legacy codebase to modern C++ will yield a better and safer codebase overall. There are multiple factors that contribute to this, such one of which is what I reffer to as "lessons learnt" if you have a stable team of developers maintaining a legacy codebase they will know where the problematic areas are and will be able to avoid re-creating them in a rewrite. An additonal factor to consider is that a lot of legacy C++ codebases can not be upgraded to use modern language features like smart pointers. The value smart pointers provide in a full rewrite can not be overstated. Then there's also the factor that is a bit anecdotal which is I find that there are less C++ devs in general as there was 15 years ago, but those that stayed / survived are generally better and more experienced with very few enthusiastic juniors coming in. I'm sorry you did not enjoy the article though, but thank you for giving it your time and reading it that part I really appreciate.
- summerlight 1y ago> in C++, you can write perfectly fine code without ever needing to worry about the more complex features of the language. You can write simple, readable, and maintainable code in C++ without ever needing to use templates, operator overloading, or any of the other more advanced features of the language. Only if you have full control on what others are writing. In reality, you're going to read a lot, lots of "clever" codes. And I'm saying as a person who have written a good amount of template meta programming codes. Even for me, some codes take hours to understand and I was usually able to cut 90% of its code after that.
- worik 1y ago> make it look as much like C as you possibly can, and avoid using too many advanced features of the language unless you really need to. Oh boy! This person needs control. That is where I left C++, a better C Faint praise
- zzrrt 1y agoI’m probably guilty of gratuitous template stuff, because it adds fun to the otherwise boring code I spend a lot of time on. But I feel like the 90% cutdowns are when someone used copy-paste instead of templates, overloads, and inheritance. I don’t think both problems happen at the same time, though, or maybe I misunderstood.
- summerlight 1y agoWhen people are obsessed with over-abstraction and over-generalization, you can often see FizzBuzz Enterprise in action where a single switch statement is more than enough.
- account42 1y agoI see that more with inheritance including pure virtual interface for things that only have one implementation and actor patterns that make the execution flow unnecessarily hard to follow. Basically, Java written in C++. Most templates are much easier to read in comparison.
- monkeyelite 1y agoThe complexity argument is just not true. You do have to know this stuff in c++, you run into it all the time. I wish I didn’t have to know about std::launder but I do
- ryao 1y agoI feel like C++ is a bunch of long chains of solutions creating problems that require new solutions, that start from claiming that it can do things better than C. Problem 1: You might fail to initialize an object in memory correctly. Solution 1: Constructors. Problem 2: Now you cannot preallocate memory as in SLAB allocation since the constructor does an allocator call. Solution 2: Placement new Problem 3: Now the type system has led the compiler to assume your preallocated memory cannot change since you declared it const. Solution 3: std::launder() If it is not clear what I mean about placement new and const needing std::lauder(), see this: https://miyuki.github.io/2016/10/21/std-launder.html https://miyuki.github.io/2016/10/21/std-launder.html C has a very simple solution that avoids this chain. Use structured programming to initialize your objects correctly. You are not going to escape the need to do this with C++, but you are guaranteed to have to consider a great many things in C++ that would not have needed consideration in C since C avoided the slippery slope of syntactic sugar that C++ took.
- monkeyelite 1y agoI absolutely agree - your chain of reasoning follows as well. It doesn't seem like it at first, but the often praised constructor/destructor is actually a source of incredible complexity, probably more than virtual.
- jcelerier 1y agoBut the c++ solution is transparent to the user. You can write entire useful programs that will use std:: containers willy-nilly and all propagate their allocators automatically and recursively without you having to lift a finger because all the steps you've mentioned have been turned in a reusable library, once.
- 1y ago
- eviks 1y ago> Yes, C++ can be unsafe if you don’t know what you’re doing. It is even if if you do > But here’s the thing: all programming languages are unsafe if you don’t know what you’re doing. But here's the thing, that's not a good argument because... > will just make it a lot harder to have memory leaks or safety issues. ... in reality it's not "just". "Just makes it better" means it's better
- s20n 1y agoI believe most C++ gripes are a classic case of PEBKAC. One of the most common complaints is the lack of a package manager. I think this stems from a fundamental misunderstanding of how the ecosystem works. Developers accustomed to language-specific dependency managers like npm or pip find it hard to grasp that for C++, the system's package manager (apt, dnf, brew) is the idiomatic way to handle dependencies. Another perpetual gripe is that C++ is bad because it is overly complex and baroque, usually from C folks like Linus Torvalds[1]. It's pretty ironic, considering the very compiler they use for C (GCC), is written in C++ and not in C. [1]: Torvalds' comment on C++ <https://harmful.cat-v.org/software/c++/linus https://harmful.cat-v.org/software/c++/linus>
- ryao 1y agoGCC was originally written in GNU C. Around GCC 4.9, its developers decided to switch to a subset of C++ to use certain features, but if you look at the codebase, you will see that much of it is still GNU C, compiled as GNU C++. There is nothing you can do in C++ that you cannot do in C due to Turing Completeness. Many common things have ways of being done in C that work equally well or even better. For example, you can use balanced binary search trees in C without type errors creating enormous error messages from types that are sentences if not paragraphs long. Just grab BSD’s sys/tree.h, illumnos’ libuutil or glib for some easy to use balanced binary search trees in C.
- AdieuToLogic 1y ago> There is nothing you can do in C++ that you cannot do in C due to Turing Completeness. While this is technically true, a more satisfying rationale is provided by Stroustrup here[0]. > Many common things have ways of being done in C that work equally well or even better. For example, you can use balanced binary search trees in C without type errors creating enormous error messages from types that are sentences if not paragraphs long. Just grab BSD’s sys/tree.h, illumnos’ libuutil or glib for some easy to use balanced binary search trees in C. Constructs such as sys/tree.h[1] replicate the functionality of C++ classes and templates via the C macro processor. While they are quite useful, asserting that macro-based definitions provide the same type safety as C++ types is simply not true. As to the whether macro use results in "creating enormous error messages" or not, that depends on the result of the textual substitution. I can assure you that I have seen reams of C compilation error messages due to invalid macro definitions and/or usage. 0 - https://www.stroustrup.com/compat_short.pdf https://www.stroustrup.com/compat_short.pdf 1 - https://cgit.freebsd.org/src/tree/sys/sys/tree.h https://cgit.freebsd.org/src/tree/sys/sys/tree.h
- doctorshady 1y agoThe one thing I'll say here is age of the language really is and always has been a superficial argument; it's only six years apart from Python, and it's far less controversial of a language choice: https://en.wikipedia.org/wiki/History_of_Python https://en.wikipedia.org/wiki/History_of_Python . Either way, it's hard not to draw parallels between all the drama in US politics and the arguments about language choice sometimes; it feels like both sides lack respect for the other, and it makes things unnecessarily tense.
- ergonaught 1y agoIt's a fine post except for this: > Countless companies have cited how they improved their security or the amount of reported bugs or memory leaks by simply rewriting their C++ codebases in Rust. Now is that because of Rust? I’d argue in some small part, yes. Just delete this. Even an hour's familiarity with Rust will give you a visceral understanding that "Rewrites of C++ codebases to Rust always yield more memory-safe results than before" is absolutely not because "any rewrite of an existing codebase is going to yield better results". If you don't have that, skip it, because it weakens the whole piece.
- mirpa 1y agoIt reminded me of Firefox attempts at rewriting part of C++ codebase and failing - because of C++ complexity; but succeeding later because of Rust https://blog.rust-lang.org/2017/11/14/Fearless-Concurrency-In-Firefox-Quantum/#stylo-a-parallel-css-engine https://blog.rust-lang.org/2017/11/14/Fearless-Concurrency-I...
- silon42 1y agoYeah... if you don't have 100% feature test coverage (and more) you will almost certainly lose features (aka cause bugs)
- nielsbot 1y ago> Yes, C++ can be unsafe if you don’t know what you’re doing I feel like I always hear this argument for continuing to use C++. I, on the other hand, want a language that doesn't make me feel like I'm walking a tightrope with every line of code I write. Not sure why people can't just admit the humans are not robots and will write incorrect code.
- blindseer 1y agoI would really like to see more people who have never written C++ before port a Rust program to C++. In my opinion, one can argue it may be easy to port initially but it is an order of magnitude more complex to maintain. Whereas the other around, porting a C++ program to Rust without knowing Rust is challenging initially (to understand the borrow checker) but orders of magnitude easier to maintain. Couple that with easily being about to `cargo add` dependencies and good language server features, and the developer experience in Rust blows C++ out of the water. I will grant that change is hard for people. But when working on a team, Rust is such a productivity enhancer that should be a no-brainer for anyone considering this decision.
- alkonaut 1y agoI'm a developer since 30 years. I program C#, Rust, Java, some TS etc. I can probably go to most repositories on github and at least clone and build them. I have failed - repeatedly - to build even small C++ libraries despite reasonable effort. And that's not even _writing any C++_. Just installing the tooling around CMake etc is completely Kafkaesque. The funniest thing happened when I needed to compile a C file as part of a little Rust project, and it turned out one of the _easiest_ ways I've experienced of compiling a tiny bit of C (on Windows) was to put it inside my Rust crate and have cargo do it via a C compiler crate.
- nly 1y agoMost of the C++ world has standardized on CMake. I work on large C++ projects with 1-2 dozen third party C and C++ library dependencies, and they're all built from source (git submodules) as part of one CMake build. It's not easy but it is fairly simple.
- DarkNova6 1y ago> Couple that with easily being about to `cargo add` dependencies and good language server features, and the developer experience in Rust blows C++ out of the water. Exactly this. Regardless of safety, expressiveness, control, whatever argument someone pulls from their hat to defend C++ the simple fact of a solid dependency manager cannot be overstated.
- kcaseg 1y agoC++ is the third programming language I ever tried to learn, I got bored and gave up on both Python and JavaScript after like a month, I now have 150 active hours of learning (I tracked) in C++, and I love it, somehow I find it mentally more stimulating, not sure why.
- codr7 1y ago4th, after basic, assembly & pascal. For a long, long time; it was my default language for personal projects. But just keeping track of all the features and the exotic ways they interact is a full time job. There are people who have dedicated entire lives to understanding even a tiny corner of the language, and they still don't manage. Not worth the effort for me, there are other languages.
- xenelor 1y agoThis reads the same way as any other 'defense', 'sales pitch', or what have you, but from a Rust evangelist. The author likes to use C++ and now he must explain to the world why his decision is okay/correct/good/etc.. If you like it that much, just use the thing; no one actually cares.
- xenelor 1y agoAs a bonus: > You can write simple, readable, and maintainable code in C++ without ever needing to use templates, operator overloading, or any of the other more advanced features of the language. It is incredibly funny how this argument has been used for literally decades, but in reality, you don't see simple, readable, nor maintainable code, instead, most of the C++ code bases out there are an absolute mess.. This argument reminds me of something...
- alkonaut 1y ago> Yes, C++ can be unsafe if you don’t know what you’re doing. But here’s the thing: all programming languages are unsafe if you don’t know what you’re doing. I think this is one of the worst (and most often repeated arguments) about C++. C and C++ are inherently unsafe in ways that trip up _all_ developers even the most seasoned ones, even when using ALL the modern C++ features designed to help make C++ somewhat safer.
- imor80 1y agoThere are two levels on which this argument feels weak: * The author is confusing memory safety with other kinds of safety. This is evident from the fact that they say you can write unsafe code in GC languages like python and javascript. unsafe != memory unsafe. Rust only gives you memory safety, it won't magically fix all your bugs. * The slippery slope trick. I've seen this so often, people say because Rust has unsafe keyword it's the same as c/c++. The reason it's not is because in c/c++ you don't have any idea where to look for undefined behaviour. In Rust at least the code points you to look at the unsafe blocks. The difference is of degree which for practial purposes makes a huge difference.
- llogiq 1y agoThe problem with C++ vs. unsafety is that there is really no boundary: All code is by default unsafe. You will need to go to great lengths to make it all somewhat safe, and then to even greater lengths to ensure any libraries you use won't undermine your safety. In Rust, if you have unsafe code, the onus is on you to ensure its soundness at the module level. And yes, that's harder than writing the corresponding C++, but it makes the safe code using that abstraction a lot easier to reason about. And if you don't have unsafe code (which is possible for a lot of problems), you won't need to worry about UB at all. Imagine never needing to keep all the object lifetimes in your head because the compiler does it for you.
- jamesdhutton 1y ago> You can write simple, readable, and maintainable code in C++ without ever needing to use templates, operator overloading, or any of the other more advanced features of the language. Maybe you can do that. But you are probably working in a team. And inevitably someone else in your team thinks that operator overloading and template metaprogramming are beautiful things, and you have to work with their code. I speak from experience.
- dayvster 1y agoThis is true and I will concede this point. Appreciate your feedback! However if I may raise my counter point I like to have a rule that C++ should be written mostly as if you were writing C as much as possible until you need some of it's additional features and complexities. Problem is when somebody on the team does not share this view though, that much is true :)
- digitalPhonix 1y ago> However if I may raise my counter point I like to have a rule that C++ should be written mostly as if you were writing C as much as possible until you need some of it's additional features and complexities. How do you define “need” for extra features? C and C++ can fundamentally both do the same thing so if you’re going to write C style C++, why not just write C and avoid all of C++’s foot guns?
- dayvster 1y agoExcellent question, I guess it depends on the team mostly how they define which features they need and which are better avoided. As for why not just go for C. You can write C++ fully as if it were C, you can not ever turn C into C++
- bregma 1y agoRAII. It's the major C++ feature I miss in C, and the one that fixes most memory leak problems in C. Also, std::vector, which solves the remaining memory leak (and most bounds problems) in C. And std::string, which solves the remaining memory leak problems.
- dayvster 1y agoAuthor of the article here. Really appreciate and value everyone's feedback on this. I can not overstate my excitement that my blog post has generated this much discussion and debate.
- jillesvangurp 1y agoC++ and C rely, heavily, on skill and discipline instead of automated checks to stay safe. Over time, and in larger groups of people that always fails. People just aren't that disciplined and they get overconfident of their own skills (or level of discipline). Decades of endless memory leaks, buffer overflows, etc. and the related security issues, crash bugs, data corruption, etc. shows that no code base is really immune to this. The best attitude in programmers (regardless of the language) is the awareness that "my code probably contains embarrassing bugs, I just haven't found them yet". Act accordingly. There are of course lots of valid reasons to continue to use C/C++ on projects where it is used and there are a lot such projects. Rewrites are disruptive, time consuming, expensive, and risky. It is true that there are ways in C++ to mitigate some of these issues. Mostly this boils down to using tools, libraries, and avoiding some of the more dark corners of the language and standard library. And if you have a large legacy code base, adopting some of these practices is prudent. However, a lot of this stuff boils down to discipline and skill. You need to know what to use and do, and why. And then you need to be disciplined enough to stick with that. And hope that everybody around you is equally skilled and disciplined. However, for new projects, there usually are valid alternatives. Even performance and memory are not the arguments they used to be. Rust seems to be building a decent reputation for combining compile time safety with performance and robustness; often beating C/C++ implementations of things where Rust is used to provide a drop in replacement. Given that, I can see why major companies are reluctant to take on new C/C++ projects. I don't think there are many (or any) upsides to the well documented downsides.
- pornel 1y agoPeople innately admire difficult skills, regardless of their usefulness. Acrobatic skateboarding is impressive, even when it would be faster and safer to go in a straight line or use a different mode of transport. To me skill and effort is misplaced and wasted when it's spent on manually checking invariants that a compiler could check better automatically, or implementing clever workarounds for language warts that no longer provide any value. Removal of busywork and pointless obstacles won't make smart programmers dumb and lazy. It allows smart programmers to use their brainpower on bigger more ambitious problems.
- ruicraveiro 1y agoStating that you can also write unsafe code in memory safe languages is like saying that you can also die from a car crash while wearing a safety belt. Of course you can, but it is still a much better idea to wear the safety belt rather than not to.
- account42 1y agoYet we don't have safety belts on a bus for example.
- chombier 1y agoI've been programming in c++ for 25 years (15 professionally) and I really don't see any reason to keep using it apart from dealing with legacy codebases. Most arguments in the article boil down to "c++ has the reputation of X, which is partly true, but you can avoid problems with discipline". Amusingly, this also applies to assembly. This is _exactly_ why I don't want to code in c++ anymore: I don't want the constant cognitive load to remember not to shoot myself in the foot, and I don't want to spend time debugging silly issues when I screw up. I don't want the outdated tooling, compilation model and such. Incidentally, I've also been coding in Rust for 5 years or so, and I'm always amazed that code that compiles actually works as intended and I can spend time on things that matter. Going back to c++ makes me feel like a caveman coder, every single time.
- selfmodruntime 1y agoExactly. I’ve been using „Stupid Rust“ for years now where I just liberally clone if I can’t have my way. It‘s not bitten me yet and once the code compiles, it works.
- mat0 1y agoWhenever I open one of these sites that asks me to confirm tracking, if it doesn’t have an easy way to cancel or reject, I just leave the page. The banner had hundreds of different companies listing “legitimate” reasons to track, and after turning off around 10, I noticed that I had hundreds to go. Sorry, I hope people enjoy your website. I just cannot see a reason to accept that amount of tracking. I don’t care that much about C++ anyway
- JonChesterfield 1y agoNone of it makes it through a pi-hole filter. Website is clean and coherent, no popups. What that implies for the attempt to track is slightly unclear to me, but I don't have great faith in the pop up box being honoured even if it loads.
- deleted 1y ago[deleted]
- cyber1 1y agoJust look at this: https://pvs-studio.com/en/blog/posts/cpp/1129/ https://pvs-studio.com/en/blog/posts/cpp/1129/ - 11 parts about C++ undefined behavior from people who specialize in finding this stuff. And that’s only the tip of the iceberg. I use C++ daily, and it’s an overcomplicated language. The really good thing about Rust or Zig is that (mostly) everything is explicit, and that’s a big win in my opinion. In defense of C++, I can only say that lots of interesting projects in the world are written in it.
- corralal 1y agoI tried to use C++ on a new project and what finally killed me was the IDE. I wanted to use the newest language version, with modules. Visual Studio's autocompletion and jump-to-definition fell apart with modules. This was demoralizing, because I was under the impression that Visual Studio was the best C++ IDE, and if it can't handle language features 4 years after their release, what does that mean? CLion or Emacs+clangd were also a pain. The editing/IDE experience has been much nicer in Rust.
- BiraIgnacio 1y agoDoes it need to be defended? Does it need to be attacked? I take the "use it if we can/want/is forced to" and "improve it if you want and can" approaches. Or else, leave it be.
- jayd16 1y agoC++ as a language is truly a mess. But as far as a niche it has a pretty unique offering, even today. My background is games and I've been heavily in Unreal lately. The language feels modern enough with smart pointers and such. Their standard library equivalent is solid. The macros still feel very hacky and, ironically, Unreal actually does its own prepass over the source to parse for certain macros.... kind of shows that it's not a good language feature if that's needed. BUT the syntax used fits right into the language, so it feels idiomatic enough. Templates are as powerful as they are just a mess to read. Does anything come close to the speed and flexibility of the language? I think the biggest reason C++ sticks around is momentum but beyond that nothing _really_ replaces the messy but performance critical nature of it.
- Joker_vD 1y ago> But Dave, what we mean by outdated is that other languages have surpassed C++ and provide a better developer experience. > Matter of personal taste, I guess, C++ is still one of the most widely used programming languages with a huge ecosystem of libraries and tools. It’s used in a wide range of applications, from game development to high-performance computing to embedded systems. Many of the most popular and widely used software applications in the world are written in C++. > I don’t think C++ is outdated by any stretch of the imagination; The second paragraph in this quote has zero connection to the first and the third paragraphs. > C++ has a large ecosystem built over the span of 40 years or so, with a lot of different libraries and tools available. Yes, exactly: it's outdated. > the simple rule of thumb is to use the standard library wherever possible; it’s well-maintained and has a lot of useful features. That's got to be the funniest joke in this whole article. First of all, no, its API is not really that well thought out and it took several language standards to finally make smart pointers and tuples truly convenient to use; and which implementation of "the standard library" do you even mean, by the way? There are several implementations of it, you know, of very varying quality. And then there is an argument against using the Boost in this article which hilariously can be well applied to C++ itself. Don't use it unless you have to! There are languages that are more modern and easier to use! > Fact is, if you wanna get into something like systems programming or game development then starting with Python or JavaScript won’t really help you much. You will eventually need to learn C or C++. The key word is eventually. You don't start learning to e.g. play guitar on a cheap, half-broken piece of wood because you'll spend more time on fighting the instrument and fiddling with it than actually learning how to play it. > New standards (C++20, C++23) keep modernizing the language, ensuring it stays competitive with younger alternatives. If you peel back the layers of most large-scale systems we rely on daily, you’ll almost always find C++ humming away under the hood. Notice the dishonesty of placing these two sentences together: it seems to imply (with plausible deniability) that those "large-scale systems we rely on daily" are written in "modern" C++. No, they are absolutely not.
- einpoklum 1y ago> Yes, C++ can be unsafe if you don’t know what you’re doing. But here’s the thing: all programming languages are unsafe if you don’t know what you’re doing. C++ can be unsafe even when you know what you're doing, since it is quite easy get something wrong by accident: index off-by-one can mean out-of-bounds access to an array, which can mean anything really. So, it's not that "all languages" are like that. That seems like a "moving the goalpost" type of logical fallacy. And I say that as a person who writes C++ for fun an profit (well, salary) and has wasted many an hour on earning my StackOverflow C++ gold badge :-) The post also includes other arguments which I find week regard C++ being dated. It has changed and has seen many improvements, but those have been almost exclusively _additions_, not removals or changes. Which means that the rickety old stuff is basically all still there. And then there is the ABI stability issue, which is not exactly about being old, but it is is about sticking to what's older and never (?) changing it. Bottom line for me: C++ is useful and flexible but has many warts and some pitfalls. I'd still use it over Rust for just about anything (bias towards my experience here), but if a language came along with similar design goals to C++; a robust public standardization and implementation community; less or none of the poor design choices of C; nicer built-in constructs as opposed to having to pull yourself up by the bootstraps using the standard library; etc - I would consider using that. (And no, that language is not D.)
- fluoridation 1y ago>So, it's not that "all languages" are like that. That seems like a "moving the goalpost" type of logical fallacy. I think what's mean is that Rust's type system only removes one specific kind of unsafety, but if you're clueless you can still royally screw things up, in any language. No type system can stop you from hosing a database by doing things in the wrong order, say. Whether trading <insert any given combination of things Rust does that you don't like> for that additional safety is worth it is IMO a more interesting question than whether it exists at all. Personally, I mostly agree with you. I don't much care for traits, or the lack of overloading and OO, or how fast Rust is still evolving, and wish I could have Rust's safety guarantees in a language that was more like C++. It really feels like you could get 90% of the way there without doing anything too radical, just forbidding a handful of problematic features; a few off the top of my head: naked pointers, pointer arithmetic, manual memory management, not checking array accesses by default, not initializing variables by default, allowing switches to be non-exhaustive.
- zenxyzzy 1y agoDon't lump c++ in with c. C++ is a nightmare amalgamation of every bad idea in software development. C is a thing of great beauty with a cheek mole. C++ is a metastatic cancer. Write disciplined, readable c, use valgrind and similar tools, and reap unequalled performance and maintainability
- einpoklum 1y agoIN MY DEFENS BJARNE ME DEFEND https://monarchies.fandom.com/wiki/In_my_defens_God_me_defend https://monarchies.fandom.com/wiki/In_my_defens_God_me_defen...