* ODR violation in ranges
@ 2020-03-11 10:08 Nathan Sidwell
2020-03-11 10:26 ` Jonathan Wakely
0 siblings, 1 reply; 8+ messages in thread
From: Nathan Sidwell @ 2020-03-11 10:08 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: GCC Patches
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)
nathan
--
Nathan Sidwell
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 10:08 ODR violation in ranges Nathan Sidwell
@ 2020-03-11 10:26 ` Jonathan Wakely
2020-03-11 10:56 ` Tam S. B.
0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2020-03-11 10:26 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: GCC Patches, libstdc++, ppalka
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?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 10:26 ` Jonathan Wakely
@ 2020-03-11 10:56 ` Tam S. B.
2020-03-11 12:47 ` Jonathan Wakely
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Tam S. B. @ 2020-03-11 10:56 UTC (permalink / raw)
To: Jonathan Wakely via Libstdc++, Nathan Sidwell; +Cc: GCC Patches
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 ).
________________________________________
From: Libstdc++ <libstdc++-bounces@gcc.gnu.org> on behalf of Jonathan Wakely via Libstdc++ <libstdc++@gcc.gnu.org>
Sent: Wednesday, March 11, 2020 10:26
To: Nathan Sidwell
Cc: libstdc++@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?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 10:56 ` Tam S. B.
@ 2020-03-11 12:47 ` Jonathan Wakely
2020-03-11 13:21 ` Patrick Palka
2020-03-11 15:05 ` Nathan Sidwell
2 siblings, 0 replies; 8+ messages in thread
From: Jonathan Wakely @ 2020-03-11 12:47 UTC (permalink / raw)
To: Tam S. B.; +Cc: Jonathan Wakely via Libstdc++, Nathan Sidwell, GCC Patches
On 11/03/20 10:56 +0000, Tam S. B. via Libstdc++ 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 yes, I think somebody (probably Patrick) has pointed out that
wording before, and I'd forgotten about it.
So that would make it an unsupported G++ feature then?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 10:56 ` Tam S. B.
2020-03-11 12:47 ` Jonathan Wakely
@ 2020-03-11 13:21 ` Patrick Palka
2020-03-11 15:05 ` Nathan Sidwell
2 siblings, 0 replies; 8+ messages in thread
From: Patrick Palka @ 2020-03-11 13:21 UTC (permalink / raw)
To: Tam S. B.; +Cc: Jonathan Wakely via Libstdc++, Nathan Sidwell, GCC Patches
On Wed, 11 Mar 2020, Tam S. B. via Gcc-patches 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 ).
>
> ________________________________________
> From: Libstdc++ <libstdc++-bounces@gcc.gnu.org> on behalf of Jonathan Wakely via Libstdc++ <libstdc++@gcc.gnu.org>
> Sent: Wednesday, March 11, 2020 10:26
> To: Nathan Sidwell
> Cc: libstdc++@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?
IIUC, it should suffice to replace the lambda in the initializer with a
function object, maybe something like:
struct _All
{
constexpr auto
operator()(...)
{
};
};
inline constexpr __adaptor::_RangeAdaptorClosure<_All> all;
Do the lambdas in the bodies of _RangeAdaptor::operator() and
_RangeAdaptorClosure::operator|() pose a problem too?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 10:56 ` Tam S. B.
2020-03-11 12:47 ` Jonathan Wakely
2020-03-11 13:21 ` Patrick Palka
@ 2020-03-11 15:05 ` Nathan Sidwell
2020-03-11 15:23 ` Jason Merrill
2 siblings, 1 reply; 8+ messages in thread
From: Nathan Sidwell @ 2020-03-11 15:05 UTC (permalink / raw)
To: Tam S. B., Jonathan Wakely via Libstdc++; +Cc: GCC Patches
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.
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++-bounces@gcc.gnu.org> on behalf of Jonathan Wakely via Libstdc++ <libstdc++@gcc.gnu.org>
> Sent: Wednesday, March 11, 2020 10:26
> To: Nathan Sidwell
> Cc: libstdc++@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
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 15:05 ` Nathan Sidwell
@ 2020-03-11 15:23 ` Jason Merrill
2020-03-11 15:39 ` Nathan Sidwell
0 siblings, 1 reply; 8+ messages in thread
From: Jason Merrill @ 2020-03-11 15:23 UTC (permalink / raw)
To: Nathan Sidwell; +Cc: Tam S. B., Jonathan Wakely via Libstdc++, GCC Patches
On Wed, Mar 11, 2020 at 11:05 AM Nathan Sidwell <nathan@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.
> 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++-bounces@gcc.gnu.org> on behalf of Jonathan
> Wakely via Libstdc++ <libstdc++@gcc.gnu.org>
> > Sent: Wednesday, March 11, 2020 10:26
> > To: Nathan Sidwell
> > Cc: libstdc++@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
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ODR violation in ranges
2020-03-11 15:23 ` Jason Merrill
@ 2020-03-11 15:39 ` Nathan Sidwell
0 siblings, 0 replies; 8+ messages in thread
From: Nathan Sidwell @ 2020-03-11 15:39 UTC (permalink / raw)
To: Jason Merrill; +Cc: Tam S. B., Jonathan Wakely via Libstdc++, GCC Patches
On 3/11/20 11:23 AM, Jason Merrill wrote:
> On Wed, Mar 11, 2020 at 11:05 AM Nathan Sidwell <nathan@acm.org
> <mailto:nathan@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++-bounces@gcc.gnu.org
> <mailto:libstdc%2B%2B-bounces@gcc.gnu.org>> on behalf of Jonathan
> Wakely via Libstdc++ <libstdc++@gcc.gnu.org
> <mailto:libstdc%2B%2B@gcc.gnu.org>>
> > Sent: Wednesday, March 11, 2020 10:26
> > To: Nathan Sidwell
> > Cc: libstdc++@gcc.gnu.org <mailto:libstdc%2B%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
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-03-11 15:39 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-11 10:08 ODR violation in ranges Nathan Sidwell
2020-03-11 10:26 ` Jonathan Wakely
2020-03-11 10:56 ` Tam S. B.
2020-03-11 12:47 ` Jonathan Wakely
2020-03-11 13:21 ` Patrick Palka
2020-03-11 15:05 ` Nathan Sidwell
2020-03-11 15:23 ` Jason Merrill
2020-03-11 15:39 ` Nathan Sidwell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).