C++ Logo

std-proposals

Advanced search

Re: Attribute view

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 19 Dec 2019 14:43:12 -0500
On Thu, Dec 19, 2019 at 8:44 AM Martin Küttler via Std-Proposals <
std-proposals_at_[hidden]> wrote:

>
> One of the main issues of std::string_view is ilustrated by the
> following example.
>
> std::string const hello = "hello";
> std::string_view s = hello + ", world";
> // access of s is UB
>
> Interestingly, this problem does not occur in the following code [because
> "reference lifetime extension"].
>
> std::string const hello = "hello";
> std::string const & s = hello + ", world";
> // access of s is fine
>
> [...] The proposed solution is to add a new attribute to the argument,

that indicates that lifetime extension is desired.

[...] Adding this attribute has two positive effects at the
> call site:
>
> - The lifetime of temporaries can be increased appropreately. This
> reduces the occurance of dangling references.
>
> - A diagnostic message can be issued if the compiler can not
> defer the destruction of the temporary long enough, e.g. when an
> object constructed with a temporary bound to a view argument is
> returned.
>

Can you give an example of what you mean here? Are you thinking of
situations like this?
// https://godbolt.org/z/Snzz4U

struct S {

    const int& r;

};


S foo() {

    S result{42};

    return result;

}


Compilers don't warn about this kind of thing today (even though arguably
they should). If you mean a slightly different case, can you give an
example? If you mean exactly this case, then are you claiming that the
existence of a standard attribute in this area would be all the
encouragement that compiler vendors have been waiting for, in order for
them to start giving diagnostics on this kind of code?


The motivation for allowing view arguments in other functions but
> constructors is twofold.
>
> - Starting in C++20, a function might be a coroutine, outliving
> the point it is called from. According lifetime is required from its
> arguments.
>

Yes. I predict lots of bugs — er, "learning opportunities" — around
coroutines.
https://quuxplusone.github.io/blog/2019/07/10/ways-to-get-dangling-references-with-coroutines/

You never give a concrete example of the syntax you're thinking of, so I'm
not sure I've got it right, but it sounds like you're asking for something
like
    class [[view]] string_view { ... };

What I thought of as soon as you said "lifetime extension" was, why don't
we turn it around and encourage people to annotate lifetime extension of
temporaries explicitly? So:

    const int& a = 42; // continues to be OK
    const int& [[extend]] a = 42; // OK, redundant, perhaps encouraged
    string_view [[extend]] result = string("hello"); // formerly
problematic, now OK
    string_view [[extend]] sv = string_view(string("hello")); // formerly
problematic, now OK (because ALL the temporaries are lifetime-extended)

Here the [[extend]] attribute on a variable definition means "compiler,
please extend the lifetimes of all temporaries used in this variable's
initializer. Extend them for the lifetime of this variable."

There's still a problem, though; temporaries can be hidden in helper
functions' bodies. So this would not help with (for example)

string_view makeSV(std::string s) { return s; } // compilers could warn
here, but in practice they don't
string_view [[extend]] oops = makeSV("hello"); // still problematic

my $.02,
–Arthur

Received on 2019-12-19 13:45:50