3 ms·
> Equating C and C++ must seem compelling when one is exposed to C++ as it is written at Mozilla and at Google. Both places enforce coding standards that requir
by pcwalton 8y ago
> Equating C and C++ must seem compelling when one is exposed to C++ as it is written at Mozilla and at Google. Both places enforce coding standards that require programming under what amount to 1990s conventions, with a few modern tricks added. The consequence is that you get few of the benefits of modern C++, but all the costs.
That's just not true. Both organizations use "modern C++" everywhere. The new C++ proposals tend to come from large companies such as Google, after all.
People tend to assume that every new release of C++ will automatically solve all the problems with the previous releases until proven otherwise. This has always mystified me. Nobody has demonstrated that any new version of C++ has been able to stem the flood of memory safety problems.
It's interesting that few people can actually articulate why modern C++ supposedly solves the memory safety issues, other than just mentioning smart pointers. Smart pointers actually do very little--shared_ptr can bump reference counts sometimes and that's about it--and what little benefit comes from smart pointers is generally outweighed by all the new ways to get use-after-free in modern C++. Free happens invisibly in subtle places in modern C++, while in C free happens explicitly when you write "free()", which tends to be safer. In my opinion, modern C++ is significantly less safe than classic C++, which is in turn significantly less safe than C.
- ncmncm 8y agoI am forced to conclude, from your complaints about the C++ code that you are exposed to, that it is very, very far from modern, for what I have to assume to be corporate reasons. I don't know why you carry on about smart pointers. I find I use unique_ptr here and there (shared_ptr, practically never), and never, ever in any interface. Instead, modern C++ code traffics in value types, and relies on destructors, almost always from a library or compiler-generated, for cleanup. Use-after-free never happens because anything freed was only ever referenced from within a value-typed object that no longer exists. The reason that, in modern C++, memory safety issues fade into insignificance is that we have access to libraries that are fully as fast as we could ever code in-line, optimized as only code that is used in many places can afford to be, that encode logic correctly, once, that can be used everywhere without compromise. Rust does not yet have the facilities to capture as much semantics in libraries. Anything Rust can't capture in a library has to be coded in place, with all the opportunities for mistakes that brings. So, Rust is good at safing low-level memory fiddling that we just don't do much of, anymore, in C++. Meanwhile, we avoid myriad errors that come from relying on necessarily leaky abstractions.
- xiphias2 8y agoI was also using unique_ptr at Google (shared_ptr is not encouraged), but the problem with unique_ptr is that it doesn't solve the more complex data ownership cases, and it's totally unusable for multi-threaded data race problems. Rust Rayon is a huge difference from anything available from C++, and it can't be solved in C++ without adding borrow checker to the C++ language (which wouldn't be a bad thing to do in my opinion, it would help modernizing old code bases).
- ncmncm 8y agoWhen you have complicated ownership cases, you have a fundamental design problem. The Standard Library is not a place to find patches for those. Likewise, multi-threaded race problems.
- xiphias2 8y agoYou can't use unique_ptr for everything if you want to have performant code. It needs heap allocation, which slows down the code base compared to stack allocated variables, in which case tracking the ownership is much more complex, but it's worth it, especially if you have millions of users.
- MaulingMonkey 8y agoSomeone still has to build those libraries full of value types, and build the necessary abstractions on top of low level pointer laden OS APIs. For a game engine programmer, that means dealing with new console hardware with new DMA controller and graphics APIs in concurrent environments where performance is critical. If anything, low-level memory fiddling is becoming more common and more widespread. Vulkan and D3D12 get lower level than ever before in what they expose. Webassembly brings pointers back to webpages like it's the 1990s and we're rocking ActiveX. I fear I'm soon going to have to start running address sanitizer for webpages. People tell me modern C++ solves this problem, but supposed examples of it invariably underwhelm me. I suspect people claiming such just have lower standards. MIRSA C can help. NASA-level piles of documentation and rules and restraint can help. Enough unit tests that you start to catch more compiler bugs than library bugs can help. Drowning the end user in the false positives produced by modern C++ static analysis tools can help. Thorough fuzz testing can help. But these are ancient techniques, not modern. Combine all that and more and, yeah, you can actually get kinda close to practicing safe C++. But this level of care is rarely practiced. No, the real problem I think is very few people are capable of the skill, patience, and fortitude to write strictly correct C++, and they rarely have the time to. And absolutely none of them were born with that power. Fresh blood will learn from their mistakes, and we will pay for those mistakes in sweat, tears, missed milestones, and CVEs. I'd love to be proven wrong. C++ pays my bills and has a great ecosystem in a lot of ways - I'd love if it were salvagable. Meanwhile, the last C++17 upgrade attempt I saw failed when we decided we were unwilling to maintain a fork of the standard library to fix compilation issues in the vendor's implementation for one of our platforms.
- quicknir 8y agoI've grepped through the codebase of Firefox some time ago, and it was very very far from being modern, with a huge amount of naked news and deletes. This is a straw man. Nobody in the C++ community action like the next release is a silver bullet. On the other hand, people in glass houses... Smart pointers help (but do not solve) memory issues by tying together access and resource destruction. If you access a resource through an object, and the resource don't go away until the object does, it makes it harder to access the resource after it's gone. Not impossible since you can do various things like grab a raw pointer/reference to the smart pointer and then call reset. In practice though, this doesn't occur that often; Murphy is a bigger problem than Machiavelli. You're entitled to your opinion but it goes directly against my experience, and most industry experience. Most C and old C++ codebases, memory management over time just becomes a tangled mess of ad hoc delete calls. With smart pointers this just hasn't happened and in practice spent tiny fractions of my time still dealing with memory related issues. A language with e.g. real reflection would be a way bigger boost to my productivity than improved memory management.