Live data from Hacker News

Modern C++ Won't Save Us (2019)

alexgaynor.net

221–230 of 266 posts

Re: Modern C++ Won't Save Us (2019)

#221
C++ is a systems programming language. Just like C, it allows you to do anything you want to do and be as close to the hardware as you want to be. This is completely unnecessary if you want to build something that displays pretty pictures on the screen in a web browser, and you really should not use C++ for a web back end unless you have really hard core performance requirements. But when you need to get close to the hardware and don't want to write assembly, your only real choices are C and C++.

To meet it's design objectives, C++ NEEDS to allow you to do things that are unsafe and it's up to you if you want to use them or not. std::span literally exists only to allow aliasing and the documentation warns you that it's up to you to to ensure that there aren't lifecycle issues. If you want lifecycle managed, don't use std::span, use copies but then you have the performance hit of copies. If you don't want either, use one of the libraries that handle reference counting for you but then you have the overhead of reference counting. If it's important not to have ANY overhead and are certain there are no scope issues, how else would you handle it? The difference between std::span and a raw pointer is mainly a) documentation for programmers reading the code and b) to make it easier for linters to find issues with how std::span is used. Similarly, if you want to capture by reference in a lambda, go right ahead but then ensuring that the underlying objects don't go out of scope is up to you.

Use something like Rust or , and you either have to lobotomize the language and give up the "safety" benefits the proponents talk about. If you don't lobotomize the language you either can't get what you want done or you give up a massive amount of efficiency.

When the rubber actually meets the road, and you try doing things like introducing Rust or to something like drivers for the Linux kernel, you immediately run into serious problems that show you why systems programming languages are needed. See for example the recent discussion about introducing drivers written in Rust into the Linux Kernel.

There are tools to do fairly hard core checking of C++ code and if you really must you can write your own for things specific to your project using the clang libraries which you can call even from python and which do much of the heavy lifting for you. These tools just aren't built into most compilers and aren't required by the standard. They are however part of most serious development workflows. Further, if you actually make the effort to learn the language, code that looks remotely like what is written for the blog post is going to set off your spidey sense in about a millisecond. Nobody said using C++ was easy. The fact that it scares of dilettantes, and that when a dilettante makes it onto the team, their lack of skill is immediately obvious in their code is a feature, not a bug. It ensures that code quality and team quality remains high.

C++ (and C) is designed to solve hard problems or achieve performance you can't with other languages. Hard things are called hard because it's difficult to do them. Otherwise they would be called easy.

If you aren't even willing to read the documentation for std::span or lambda captures or plausibly read them and choose to use them in ways the documentation tells you will cause problems for a blog post, you are just wasting everyone's time.

Note that there is in fact a recommended subset and set of code guidelines of the C++ language that it's suggested be used for new projects. Still under development and heavy revision but already very useful. https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines. clang-tidy has options to check for conformance to these and much more. The Core Guidelines aren't going to allow you to start writing production quality C++ in a day or anything like that. There will still be a steep learning curve. But if you setup your linters properly and read the Core Guidelines (and a couple of good C++ books) you won't be quite as bewildered about how to start.

Re: Modern C++ Won't Save Us (2019)

#222
post #15

Clang gives a warning for the first example: :7:25: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] https://godbolt.org/z/zTnjbhMqr

Yeah, and clang-tidy gives another; I just typed the first example and got both -Wdangling-gsl and "Std::basic_string_view outlives its value [bugprone-dangling-handle]" from clang-tidy. It doesn't invalidate the point of the article, that these things perhaps should be easier to avoid, or impossible to express. You can code safe-ish C++ with high warnings settings and enough liters and static analysis tools backing…

I changed teams at work (Google) to one that uses a C++ codebase that has survived for 20 years. As someone writing C++ for the first time, clang-tidy has been huge. It stops so many screw ups before I get to the code reviewer.

I've not found C++ as bad as I worried, partly because Google's style guide limits the amount of silliness you can do, partly because I have avoided memory issues by just never allocating to the heap using `new` with smart pointers, but mostly because Clang and Clang-Tidy have helped me avoid all the footguns.

I wouldn't write a new project in C++ (especially outside Google where the package management ecosystem is non-existant), but I'm no longer of the opinion that I would never join a team just because their current codebase was written in C++.

Re: Modern C++ Won't Save Us (2019)

#223
The typical, well known blog pattern for writing against C++: Show some buggy code an then conclude that C++ is wrong. Instead of asking: Who is wrong, the programmer trying to speak the language or the language itself? As always: Only use what you understand how it works. Instead of directly escalating it to cardinal questions of language superiority he had better used his time constructively and wrote a tutorial on how to correctly use things like string_view and span, that are a typed reference to memory that exceed the live time of the string_view.

Re: Modern C++ Won't Save Us (2019)

#224

The typical, well known blog pattern for writing against C++: Show some buggy code an then conclude that C++ is wrong. Instead of asking: Who is wrong, the programmer trying to speak the language or the language itself? As always: Only use what you understand how it works. Instead of directly escalating it to cardinal questions of language superiority he had better used his time constructively and wrote a tutorial on…

> Who is wrong, the programmer trying to speak the language or the language itself?

This is more complicated a question than you think. If the language is such that you always have to look up some particular feature, then it's likely the language is wrong in that the designer chose that syntax poorly. OTOH, if the programmer just "threw something together" that happened to be incorrect, then obviously the programmer.

This latter example is actually where having good error-messages can come in: pointing out what is wrong, and perhaps some relevant location in the language-definition. — Compare and contrast Ada and C++ error-messages (for "typical implementations") here as an example.

Re: Modern C++ Won't Save Us (2019)

#225
This was a troll blog. Cannot believe people keep beating this dead horse. This is a troll post to promote Rust.

We are not doomed. There are no such thing called "save"

That Rust zealot claimed in the other blogs that using C or C++ violates human rights.

He claimed memory safety issues in Rust are impossible however https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=rust shows there are a huge amount of memory CVEs in rust.

Sure modern C++ does not prevent all memory safety issues, neither Rust did.

Re: Modern C++ Won't Save Us (2019)

#226

Earlier quoted context omitted.

A nice, obvious way to get a per session arena for almost all resources is to fork a process.

Um, yeah, but there are other issues that make it not so nice. And it's an inoperative concept for most kernel/embedded work. I'd say in most contexts where forking would be OK you should be using a GC language anyway.

> And it's an inoperative concept for most kernel/embedded work

I recently integrated mini_httpd (a small forking server) into an embedded system as part of a solution for distributing updates across a cluster of these systems.

You must be talking about 15 cent microcontrollers (that still have a TCP/IP stack with SSL) or something, not ARM cores with MMU's running Linux.

Re: Modern C++ Won't Save Us (2019)

#227
post #24

My comment for too many years is that C/C++ fails to deal with three issues: "How big is it", "Who owns it", and "Who locks it". C++ has, with difficulty, made progress on "How big is it" through templates, but raw pointers keep leaking out. "Who owns it" has been tough to deal with, although "owned pointers" at least try. "Who locks it" has yet to be addressed at the language level, although at least there's now som…

>My comment for too many years is that C/C++ fails to deal with three issues: "How big is it", "Who owns it", and "Who locks it".

Ada has is pretty good at dealing with all three of these, TBH.

"How big is it" — Given by the 'Size attribute, and representation-clauses explicitly control record-layout.

"Who owns it" — The declaring entity, which is why you can have dynamically-sized arrays without heap-allocation and "allow the scope to clean things up".

"Who locks it" — a bit more convoluted than the above, but generally one of several options: (1) the Task / protected-object via entries; (2) the object itself, via controlled/limited_controlled inheritance; OR (3) the subprogram/compilation-unit via parameter-passing and/or interface-control (i.e. the only way to alter the interior-value is by some exported interface).

Re: Modern C++ Won't Save Us (2019)

#228
post #77

the problem I see with the author's very narrow point of view is that Rust, C++ or C are just tools which can all be misused and produce defects when used improperly or without a good understanding. Rust borrow checker can be implemented in a C++ compiler on a subset of the language which is ironically also what rust does, unsafe parts of Rust well are still unsafe... Already C++ compilers and static analyzers (thank…

Honestly Rust to me feels like a go-ish version of C++ with a modern compiler that has -Wall -Werror enabled by default

Agreed! It's a tough world out there in the fight for relevance. Besides Go and Rust in the recent languages that more or less clamor to compete with C++ are Swift, Nim, Zig, D etc. and honestly I don't know if Rust or any of those will save us from human error or incompetence.

Re: Modern C++ Won't Save Us (2019)

#229
post #24

My comment for too many years is that C/C++ fails to deal with three issues: "How big is it", "Who owns it", and "Who locks it". C++ has, with difficulty, made progress on "How big is it" through templates, but raw pointers keep leaking out. "Who owns it" has been tough to deal with, although "owned pointers" at least try. "Who locks it" has yet to be addressed at the language level, although at least there's now som…

I think the biggest problem with C++ is the lack of explicit safety requiring you understand the internal mechanisms of how everything works in order to make use of almost anything, combined with extremely high levels of abstraction. The high levels of abstraction are powerful, but quickly become footguns to the uninitiated (and the initiated alike at times). > Figuring out how to do something safely can be quite dif…

> footguns to the uninitiated

Well, that depends on the uninitiated. Those who come from a more "user-friendly" language, e.g. Java, are pretty much safe - they can continue with C++ and its Standard Library as if it was Java (as long as they respect the RAII principle). The C people, on the other hand, should expect to be bitten on the ass many times (try, for example, to use the pointer to an element of an std::vector after you have pushed some more elements into it!), and so you are right, those people are, unfortunately, better off knowing the internals.

Re: Modern C++ Won't Save Us (2019)

#230
post #24

My comment for too many years is that C/C++ fails to deal with three issues: "How big is it", "Who owns it", and "Who locks it". C++ has, with difficulty, made progress on "How big is it" through templates, but raw pointers keep leaking out. "Who owns it" has been tough to deal with, although "owned pointers" at least try. "Who locks it" has yet to be addressed at the language level, although at least there's now som…

> three issues: "How big is it", "Who owns it", and "Who locks it" The issue with this kind of thinking is the belief that there is a "it", not "they". Say, you are writing a HTTP server [1]. A beginner mindset (what seems to be demonstrated in this post) with start allocating left and right, for every HTTP header, for every piece of string, for every piece of metadata record, etc. Thus, "how big is it" become no big…

> You allocate a memory arena when the HTTP request comes. From that point on, every "allocation" is equivalent to bumping a pointer in that arena. If the arena gets full, we allocate another and chain it to the previous one, as a linked list.

Didn't you just describe the regular memory management as applied by OS in a process scope? At the completion of the process, all memory allocated by the process is reclaimed.

On some systems this approach is combined with granular quotas to allow multi-process coexistence.

Shifting this sort of memory management over to application scope may yield benefits now, but ultimately it's an OS-level concern.

Post reply on HN