4 ms·
As someone who has worked in C/C++ on teams for a while. My personal opinion is that safe C++ programmers never use pointers - put everything on the stack and
by munk-a 3y ago
As someone who has worked in C/C++ on teams for a while. My personal opinion is that safe C++ programmers never use pointers - put everything on the stack and use (usually const) references.
But I've really got to ask - at that point do you really want to program in C++ anymore or is it just better to use a safer language that removes pointers entirely?
- LoganDark 3y agoDo "references" even exist in C? Aren't they a C++ thing? How do you manage heap allocations without ever touching a pointer?
- munk-a 3y agoEdited for correctness - I was indeed talking about C++ and references are relevant only in C++. C absolutely has stack allocations which can make things a fair bit safer but if you're passing around collections it's usually done by pointer just to avoid copy actions.
- LoganDark 3y agoC has VLA, but I think C++ can still use alloca, although that returns a pointer still.
- UncleMeat 3y agoAnd this still permits oodles of memory safety issues. You can have lifetime problems with stack-use-after-return. You can have bounds checking issues on stack allocated arrays. You can have data leakage through use of uninitialized memory. And while there are some kinds of applications where never performing heap allocations is viable, this design is simply not an option for a huge number of applications.
- butlerm 3y agoIt is basically impossible to write general purpose software like compilers, word processors, and layout engines without doing heap allocations. That means either pointers or references, which are difficult to distinguish if you do not engage in pointer arithmetic. Any C++ program that does not do heap allocations either uses arrays as a substitute for the same thing or isn't a general purpose application.
- jandrewrogers 3y agoThere are categories of software for which C++ is still the clear best choice due to its superior expressiveness as a systems language. There are also other types of safety beyond memory safety that are better supported in C++ than other systems languages. As a practical matter I haven't seen a pointer issue in years, working from a C++17 foundation, so the expressiveness and other safety benefits are more valuable than a lack of a borrow checker or garbage collector. I use safer languages when appropriate but there are cases where they would introduce more bugs than they address.
- estebank 3y ago> There are also other types of safety beyond memory safety that are better supported in C++ than other systems languages. Such as? Genuinely curious.
- jandrewrogers 3y agoC++20 has very powerful compile-time metaprogramming and generics facilities. As a consequence, you can codegen complex systems of data structures and algorithms that are verified to be both optimal and safe at compile-time, essentially from a specification. The ability to automagically infer and codegen use-case specific types means that there are almost no naked primitive ‘int’ and similar types anywhere, the types are restricted to what they need to express and little more. While there is some ability to formally verify the correctness of these type interactions at compile-time, it is limited as a practical matter. The real strength is the ability verify the properties pretty exhaustively at runtime, given sufficiently good testing. If you implement something like a database kernel almost entirely in user space, which is what you want to do if you care about performance, you have a new set of problems that languages like Rust were not designed to solve. Ownership, mutability, and lifetimes are not resolvable for most objects at compile-time, they can only be resolved dynamically at runtime. With C++, you can make these look like ordinary objects with ordinary behaviors, with metaprogramming abstractions under the hood arbitrating the chaos. Things that look unsafe are actually guaranteed safe by the underlying abstractions. In this type of software, almost your entire address space is “unsafe” in some way, so it is enormously useful to be able to overlay a safety model that does not rely on the compiler, since the compiler cannot solve these cases. I use both C++ and Rust in production environments. There are cases where C++ used well is legitimately safer, theoretically and empirically, which is why I still use C++ for some things. Rust may become stronger at dealing with these cases but it still has many years to go. (Also, Rust async story is a hot mess, and you really need async for scalable, performant systems software.)