On 3/11/20 11:23 AM, Jason Merrill wrote:
On Wed, Mar 11, 2020 at 11:05 AM Nathan Sidwell <nat...@acm.org <mailto:nat...@acm.org>> wrote:

    On 3/11/20 6:56 AM, Tam S. B. wrote:
     > IIUC using lambda in inline variable initializer is not ODR
    violation. This is covered in CWG 2300 (
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1510r0.html#2300
    ).

    ah, thanks for the pointer.  For lambdas in function scope we do
    achieve
    this (the mangling of the lambda uses the function as scope and a
    function-specific index).

    We do not do so for lambdas in the initializer of namespace-scope
    inline
    variables, which is I think the missing bit.  That's an ABI thing, I'll
    ask over there.


Looks like the condition on the call to start_lambda_scope in cp_parser_init_declarator just needs to be adjusted to handle non-template inline variables.

thanks!

The ABI does describe how to mangle these (it focusses on data-members, but AFAICT works for namespace-scope vars too). We don't do any of that though :(


    The ranges header we'll die horribly if we ever emit non-inline code to
    evaluate the lambda at runtime.  We'll give it a name that depends on
    the order of (namespace-scope?) lambdas. :(

    inline constexpr auto foo = [] (int i) {return i * 2;};
    int bob (int i)
    { return foo (i); }

    compile with -fno-inline and observe '_ZNKUliE_clEi'

    sigh,

    nathan
     >
     > ________________________________________
     > From: Libstdc++ <libstdc++-boun...@gcc.gnu.org
    <mailto:libstdc%2b%2b-boun...@gcc.gnu.org>> on behalf of Jonathan
    Wakely via Libstdc++ <libstd...@gcc.gnu.org
    <mailto:libstdc%2b...@gcc.gnu.org>>
     > Sent: Wednesday, March 11, 2020 10:26
     > To: Nathan Sidwell
     > Cc: libstd...@gcc.gnu.org <mailto:libstdc%2b...@gcc.gnu.org>; GCC
    Patches
     > Subject: Re: ODR violation in ranges
     >
     > On 11/03/20 06:08 -0400, Nathan Sidwell wrote:
     >> Jonathan,
     >> the ranges header contains code like:
     >>     inline constexpr __adaptor::_RangeAdaptorClosure all
     >>       = [] <viewable_range _Range> (_Range&& __r)
     >>       {
     >> if constexpr (view<decay_t<_Range>>)
     >>    return std::forward<_Range>(__r);
     >> else if constexpr (requires {
    ref_view{std::forward<_Range>(__r)}; })
     >>    return ref_view{std::forward<_Range>(__r)};
     >> else
     >>    return subrange{std::forward<_Range>(__r)};
     >>       };
     >>
     >> (line 1236)
     >>
     >> When you strip away all the templateyness, you have:
     >>
     >>
     >> inline constexpr auto all = [] () {};
     >>
     >>
     >> That's an ODR violation -- the initializers in different TUs are not
     >> the same!
     >>
     >> As you can guess, I can't turn this into a header unit (well, I can,
     >> but merging duplicates complains at you)
     >
     > CC libstdc++@ and Patrick.
     >
     > I did wonder if using lambdas for those global variables would be OK.
     >
     > I think we'll need a new class template for each view adaptor, rather
     > than using the _RangeAdaptorClosure to hold a closure.
     >
     > Patrick, can you look into that please?
     >


-- Nathan Sidwell



--
Nathan Sidwell

Reply via email to