C++ "Lifetime Profile 1.0", a.k.a. C++ might get a sort of borrow checker


#1

https://herbsutter.com/2018/09/20/lifetime-profile-v1-0-posted/ is Herb’s announcement blog post with links to the proposal, his cppcon talk about it and a bunch of godbolt examples.

https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf is the latest form of the proposal itself.

Similarities to Rust include:

  • each function checked in isolation; no interprocedural analysis
  • all “uses” of a variable are either a “move”, a “non-const use” or a “const use”
  • when a value gets moved, non-const used or reaches the end of its scope, all Pointers to it are invalidated
  • based on a CFG (which makes it a little more like NLL than the current borrow checker)
  • “by default we assume that a function returns values that are derived from its arguments” is roughly the same as our “lifetime elision”
  • “aggregate” types are treated as if each field was a separate variable (or as we say in Rust, the compiler understands that borrows of disjoint fields don’t alias)

Differences from Rust include:

  • a Pointer being non-const doesn’t imply it’s unique
  • No attempt to inspect the contents of user-defined types. Instead, it relies on each type being explicitly annotated as a [[gsl::Pointer]], [[gsl::Owner]], etc. This is why I said “Pointer” with a capital P above; in this proposal that term refers collectively to raw pointers, references, smart pointers, std::string_view, etc.
  • more complex cases like std::vector<std::string_view> don’t get checked as thoroughly
  • Explicit annotations are much more verbose, and don’t involve lifetime parameters. “For example, void f(int* p, int* p2 [[gsl::lifetime({p})]]) expresses that p2 must point to the same thing as p.”
  • as you’d expect, no whole program soundness guarantees

So far I haven’t noticed anything that suggests a potential improvement to Rust’s borrow checking, but there are a lot of details I haven’t fully digested yet, and it’s interesting regardless.


#2

This would be a major improvement to C++ if done well, IMHO, but it really depends on the error messages. Currently, STL error messages are enough to scare small children and adults alike.


#3

Associated talks:

  • From the first talk and the abstract in Sutter’s .pdf it seemed to me that this was opt-in warnings (i.e. lints) rather than type checking errors? Is that correct?

  • I’m a bit confounded as to why there are zero mentions of Rust in any of these resources…

  • I’m a fan of improving correctness everywhere so this seems nice.

Preach!


#4

Probably because Rust is a young language. My guess is that designers of more mature languages just don’t know enough about Rust to learn from it. The same can be observed in some of the Go 2.0 design proposals, especially around generics, interfaces, and breaking changes/compatibility.

Keeping in mind that I haven’t read/watched anything at all yet, this sounds like backwards compatibility. C++ has taken the path of backwards compatibility that chooses to make each new version of C++ a strict superset of all previous versions. That’s why C++ syntax has gotten progressively more bizarre (have you seen the lambda syntax?) and keywords get longer (e.g. reinterpret_cast<T>(foo)).

My guess is that there are exactly 0 existing C++ programs that would pass a hypothetical Rust-style C++ borrow checker, especially when you factor in libc et al. That seems to suggest that the best C++ can hope for is really nice error messages. However, I’m not sure if C++'s current design patterns would benefit from a borrow checker (e.g. shared mutable state is pretty common).


As a side note, it’s going to be really interesting to see how C++ vs Rust vs Go’s approaches to backwards compatibility end up panning out. It seems that everyone has learned from python’s strategy and opted to do something else. Live and learn!


#5

They did mention Rust tho. :slight_smile: What I found odd about the Go 2.0 design proposals was that they didn’t mention Haskell (which is a mature language that has existed for a long time…) and didn’t have a proper discussion about type classes.

Yeah; I also think they couldn’t do more than this…


#6

I am pretty sure that Herb Sutter knows something about Rust and this proposal was to some degree inspired by Rust. After all Bjarne Stroustrup has attended panel discussion with Niko in 2014 and he collaborated with Herb on the proposal.

There are no mentions of Rust because there aren’t usually any links to other languages in the C++ proposals and talks even when the feature presented is copy-pasted from different language. Don’t ask me why.


#7

The aforementioned panel discussion:

Interesting; Our approach is diametrically opposite here. We even have a “Prior art” section in the template.


#8

Maybe it’s just me but that sounds a lot like the C++ proposal people not quoting a/the source that did the hard work for them i.e. it’s not very social.