[cfe-dev] [RFC] Upstreaming Lifetime Function Annotations

Dmitri Gribenko via cfe-dev cfe-dev at lists.llvm.org
Fri Dec 13 01:57:14 PST 2019

Hi Herb,

On Thu, Dec 12, 2019 at 7:34 PM Herb Sutter <herb.sutter at gmail.com> wrote:

> Gábor wrote:
> > I would love to see a simpler syntax. I think implementing this the most
> general
> > way possible and adding some syntactic sugar later on after having some
> data
> > about the most common patterns might make sense.
> Yes. In particular, the nicest “nice syntax” of all is intended by design
> to be *whitespace* for the large majority of functions, via defaults that
> are equivalent to default annotations… the Lifetime design paper
> <https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf>
> proposes such defaults (in sections 2.5.3 and 2.5.5), and the aim is that
> very few functions ever want explicit annotation.
> So far in our experience that has been working very well, including that
> the large majority of std:: standard library functions just work unchanged
> without annotation:
>    - To see basic examples, please look at https://godbolt.org/z/1C4t8m
>    (which involves std::min) and https://godbolt.org/z/4G-8H- (which
>    diagnoses a StackOverflow question involving unique_ptr). No annotation of
>    the standard library was needed in either example, they use the stock
>    unmodified std:: implementation.*
>    - For an (IMO pretty slick) example of zero-annotation of more complex
>    code, see https://godbolt.org/z/eqCRLx – the code it diagnoses is
>    actually quite complex (vector push_back but also ranges with filtering
>    views) and all unannotated, and it gives nice and accurate diagnostics
>    (pretty much “hey, your ranges::view::filter is dangling here on line B,
>    because your vector<int>.push_back() invalidated it here on line A”).
>    - See also section 2.6.2 in the design paper which shows that the
>    string_view dangling problem examples given in WG21 paper P0936 are (I
>    think all) diagnosed without any explicit annotation, because the proposed
>    defaults do the right thing.
> Those are examples, many of them drawn from real-world code, that needed
> no annotation at all with the proposed default annotations.
> So I would propose this:
>    1. Implement the general form. We know that occasionally we’ll need
>    that, and then we can express anything in #2 and #3 as equivalents/sugars
>    for something expressible in #1.
>    2. Implement the proposed default rules (including tweak them as we
>    gain experience in larger codebases) so that whitespace zero-annotation
>    Just Works for (we hope) a very large number of functions.
>    3. Then see if we actually need any in-between syntactic sugars at
>    all. If #2 covers a sufficiently high % of functions, we may not even be
>    interested in other sugars. And if we discover there are patterns that #2
>    doesn’t cover well, then we can add sugars for those patterns.
> How does that sound?

I have studied your paper in detail quite some time ago, so I'm familiar
with the proposed inference rules -- but thanks for reminding me. I'm still
skeptical that the explicit annotations would be rare enough that
readability of the general syntax is irrelevant. Anyway, the only way to
find out is to try to annotate real-world code, and for that we need
tooling support first (e.g., this warning) to find where we need
annotations. While it is good that the standard library required few
annotations, I don't think the standard library is representative of
real-world business logic that engineers write today, or of legacy data
structures and APIs that companies have accumulated over the decades.

In other words, I agree with your plan, but I think the chances are very
low that we won't need to do anything in #3.

* As a temporary implementation detail, the prototype does currently
> hardwire knowledge that unique_ptr and vector are owners, but there also
> proposed default zero-annotation rules for automatically recognizing which
> types are Owners (see section 2.1) which recognize those types without
> annotation (e.g., it recognizes containers and smart pointers as implicitly
> Owners).

I actually think that annotating owner types is a good idea. The cost of an
inference failure for an owner type is too high, and debugging it would be
non-trivial even for experts (what did *exactly* prevent this type from
being inferred to be an owner?) Annotating owners is also good as a matter
of documentation. I am not worried about annotation cost for owner types,
since they are going to be quite rare.


(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20191213/1c93115a/attachment.html>

More information about the cfe-dev mailing list