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