Live data from Hacker News

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

alexgaynor.net

11–20 of 266 posts

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

#11

It's interesting that one of the things C++ got right was having value semantics by default and most of these "problems" are the result of using either references or types that behave like dumb references/pointers such as std::string_view.

Value semantics as in "copy constructor for everything" is only helpful in limited ways.

What is helpful is move semantics for anything mutable, which was introduced quite recently.

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

#12
post #6
post #2

UB-invoking dereference in std::optional is such a baffling design choice. The whole point of an optional type is to prevent accidental unchecked access to the value. Sure, sometimes it's useful for performance to skip the check when it's already known-safe from the context, but such dangerous optimization should have been behind a method like `beware_of_the_nasal_demons()`, not an innocent-looking convenience syntax…

> The whole point of an optional type is to prevent accidental unchecked access to the value. You might argue it should be that, but it wasn't my impression that it is that. My impression was std::optional is just there to allow for representing the absence of a value. Ideally that should be zero-overhead, which means dereferencing it should degenerate into a normal object access. Hence the current design.

>Ideally that should be zero-overhead

Optionals are not zero-overhead in any other language. If you aren't going to bother checking the optional, why not just return any old pointer type? The type system should be used to enforce a contract and bypassing checks on that feels like you are just spitting in the fact of the type checker.

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

#13
post #2

UB-invoking dereference in std::optional is such a baffling design choice. The whole point of an optional type is to prevent accidental unchecked access to the value. Sure, sometimes it's useful for performance to skip the check when it's already known-safe from the context, but such dangerous optimization should have been behind a method like `beware_of_the_nasal_demons()`, not an innocent-looking convenience syntax…

> not an innocent-looking convenience syntax for flirting with the UB

I agree, but C++ uses this pattern in so many places that I think it is less confusing to be consistent. When I see a nice, concise syntax or function, I check cppreference for undefined behavior...

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

#14
C++ is a beautiful, pragmatic and very efficient language, just constrain your use of it to STL, and avoid Boost and other over-engineered dependencies.

The Ockham's razor principle of code design is not only important but essential when using large mature languages that have many surprising and nuanced ways to skin a cat. Being too clever with C++ is a recipe for disaster.

Avoid OOP (inheritance in particular) and the sacred art of templates metaprogramming, but also avoid the lowlands of using C++ as a version of C language (with malloc everywhere), and you shall be rewarded in this life or next.

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

#16
post #6

Earlier quoted context omitted.

> The whole point of an optional type is to prevent accidental unchecked access to the value. You might argue it should be that, but it wasn't my impression that it is that. My impression was std::optional is just there to allow for representing the absence of a value. Ideally that should be zero-overhead, which means dereferencing it should degenerate into a normal object access. Hence the current design.

> Ideally that should be zero-overhead Optionals are not zero-overhead in any other language. If you aren't going to bother checking the optional, why not just return any old pointer type? The type system should be used to enforce a contract and bypassing checks on that feels like you are just spitting in the fact of the type checker.

> Optionals are not zero-overhead in any other language.

That's been true for so many other features in C++ too.

> If you aren't going to bother checking the optional, why not just return any old pointer type?

Pointers require something to point to. Optionals can embed the value.

> The type system should be used to enforce a contract and bypassing checks on that feels like you are just spitting in the fact of the type checker.

It's bypassing something alright, but I wouldn't say that's the type checker. And I mean, you could use this logic for everything else. Iterators, arrays, etc. should all have bounds checking too, right? If you want that, there's C#...

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

#17
post #10

> There are significant challenges to migrating existing, large, C and C++ codebases to a different language – no one can deny this. Nonetheless, the question simply must be how we can accomplish it, rather than if we should try. Um... no. Not every (or even most ) existing large C/C++ codebase should be migrated to another language. "But security vulnerabilities! And crashes!" I admit all that. But a program can be…

I read that sentence as applying to security-critical software. i.e., I don't think the author would insist that Quake II be rewritten in Rust.

Quake III already has been ;)

https://immunant.com/blog/2020/01/quake3/

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

#18
post #6

Earlier quoted context omitted.

> The whole point of an optional type is to prevent accidental unchecked access to the value. You might argue it should be that, but it wasn't my impression that it is that. My impression was std::optional is just there to allow for representing the absence of a value. Ideally that should be zero-overhead, which means dereferencing it should degenerate into a normal object access. Hence the current design.

> Ideally that should be zero-overhead Optionals are not zero-overhead in any other language. If you aren't going to bother checking the optional, why not just return any old pointer type? The type system should be used to enforce a contract and bypassing checks on that feels like you are just spitting in the fact of the type checker.

  > why not just return any old pointer type?
Using a pointer type in a straightforward manner would entail allocating the object on the heap.

If allocated on the stack it has obvious lifetime limitations.

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

#19
post #6
post #2

UB-invoking dereference in std::optional is such a baffling design choice. The whole point of an optional type is to prevent accidental unchecked access to the value. Sure, sometimes it's useful for performance to skip the check when it's already known-safe from the context, but such dangerous optimization should have been behind a method like `beware_of_the_nasal_demons()`, not an innocent-looking convenience syntax…

> The whole point of an optional type is to prevent accidental unchecked access to the value. You might argue it should be that, but it wasn't my impression that it is that. My impression was std::optional is just there to allow for representing the absence of a value. Ideally that should be zero-overhead, which means dereferencing it should degenerate into a normal object access. Hence the current design.

Do you mean that the purpose of std::optional is to be faster than a pointer (which could represent absence as nullptr)? I would have thought it would be ML-style safety, but it seems like you're right. I guess a tagged union (or std::pair) would be faster—if the std::pair is a local variable, fields of the wrapped object will be at fixed offsets from your stack pointer or frame pointer, so you save yourself an indexed register load the first time you access a field of the object. That seems to have been the intended use.

Why did they think this was a good idea?

Post reply on HN