Skip to content

Design note: Unsafe code

Herb Sutter edited this page Oct 2, 2022 · 4 revisions

Q: Should we be able to implement very-low-level facilities in Cpp2? If so will it have unsafe blocks/functions?

A: Yes, I intend that we can write full programs in Cpp2 syntax only. No, I'm not a fan of "unsafe" as a monolithic hammer, I want to be able to declare my intent of which rules I want to break and suspend only those.

My view of this is the same as we do in the C++ Core Guidelines... code should be able to [[suppress <specific-rule>]] in a statement or expression, which is explicit and greppable, if it wants to violate a specific rule.

I don’t like monolithic "unsafe" that turns off checking for all rules, because it doesn't express the programmer's intent. The programmer usually doesn’t want to disable all rules, just one specific one. With a monolithic "unsafe," if the same statement accidentally violates a second unrelated rule than we lose diagnosing that unintended bug.

For example, if I want to just do an explicit unsafe cast, in today's syntax something like this:

... reinterpret_cast<PodType&>(myspan[idx]) ...

If my goal is to say "let me reinterpret-cast already!" then I want to write something like [[suppress unsafe-type-cast]] or similar on that statement. But just because I want to opt into doing the cast doesn't mean I want to turn off span bounds checking on the index operation! If the same statement also does something else that's potentially unsafe, I still want that to be flagged -- that's important.

If all I can do is write a monolithic "unsafe, remove all guard rails now" hammer to enable the cast that I did intend to write, I would suppress also the bounds-safety check and not flag the bounds mistake that I didn't intend to write in the same statement. That would be an "oops."

I'm not sure what a good analogy is here, but let's try this: If I want to turn on the bandsaw, I want independent protective covers on the bandsaw power button and the nuclear missile launch button, not a single cover over both that makes them unavailable/available together and then have to remember not to accidentally use the one I don't want to use today. Today I only want to cut some wood; I still want be around tomorrow to use the wood for my treehouse.