* 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).