Boost logo

Boost :

Subject: Re: [boost] Any-Range containing transformed range fails when compiled with optimizations
From: Andrey Davydov (andrey.a.davydov_at_[hidden])
Date: 2016-01-16 12:44:47


I am sorry if it's obvious, but there is simple workaround: add 'const' to
third template argument of boost::any_range.
[using R = boost::any_range<SourceEvent, boost::forward_traversal_tag, const
SourceEvent, std::ptrdiff_t>;]
In that case boost::any_forward_iterator_wrapper<...>::reference become
'SourceEvent' instead of 'SourceEvent &', and returning address of local
variable will be prevented.

On Thu, Jan 14, 2016 at 11:28 PM, Auer, Jens <jens.auer_at_[hidden]> wrote:

> Hi,
>
> I have a program which produces different results based on the compiler
> options. The program uses a boost::any_range containing a transformed range
> where the transformation function just returns a new object of a simple
> struct:
> #include <vector>
> #include <boost/range.hpp>
> #include <boost/range/any_range.hpp>
> #include <boost/range/adaptor/transformed.hpp>
> #include <iostream>
>
> template<typename T1, typename T2> void ASSERT_EQ(T1 x,T2 y) {assert(x ==
> y);};
>
> struct SourceEvent
> {
> std::uint32_t event;
> void* ptr;
> };
>
> int main()
> {
> using boost::adaptors::transformed;
>
> using R = boost::any_range<SourceEvent, boost::forward_traversal_tag,
> SourceEvent, std::ptrdiff_t>;
> std::vector<std::int32_t> v(100);
> R r = v | transformed( [](auto const&) {return SourceEvent{0u,
> nullptr};} );
> auto t = v | transformed( [](auto const&) {return SourceEvent{0u,
> nullptr};} );
>
> ASSERT_EQ( 100u, boost::size(r) );
> ASSERT_EQ( 100u, boost::size(t) );
>
> for (auto const& i: t)
> {
> ASSERT_EQ(0u, i.event );
> ASSERT_EQ(nullptr, i.ptr);
> }
>
> for (auto const& i: r)
> {
> ASSERT_EQ(0u, i.event );
> ASSERT_EQ(nullptr, i.ptr);
> }
>
> std::cout << "OK" << std::endl;
>
> return 0;
> }
>
> When compiled without optimization, it just prints ok. The same source
> compiled with optimizations asserts, and prints some interesting warnings:
>
> In file included from
> /usr/local/boost-1.60.0/include/boost/range/detail/any_iterator.hpp:22:0,
> from
> /usr/local/boost-1.60.0/include/boost/range/any_range.hpp:17,
> from prog.cc:3:
> /usr/local/boost-1.60.0/include/boost/range/detail/any_iterator_wrapper.hpp:
> In member function
> 'boost::range_detail::any_forward_iterator_wrapper<WrappedIterator,
> Reference, Buffer>::reference
> boost::range_detail::any_forward_iterator_wrapper<WrappedIterator,
> Reference, Buffer>::dereference() const [with WrappedIterator =
> boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(const
> auto:1&)>, SourceEvent>, __gnu_cxx::__normal_iterator<int*,
> std::vector<int> >, boost::iterators::use_default,
> boost::iterators::use_default>; Reference = SourceEvent; Buffer =
> boost::any_iterator_buffer<64ul>;
> boost::range_detail::any_forward_iterator_wrapper<WrappedIterator,
> Reference, Buffer>::reference = SourceEvent&]':
> /usr/local/boost-1.60.0/include/boost/range/detail/any_iterator_wrapper.hpp:302:57:
> warning: function may return address of local variable [-Wreturn-local-addr]
> return dereference_cast<reference>(*m_it);
> ^
> /usr/local/boost-1.60.0/include/boost/range/detail/any_iterator_wrapper.hpp:302:52:
> note: declared here
> return dereference_cast<reference>(*m_it);
> ^
>
>
> prog.exe: prog.cc:7: void ASSERT_EQ(T1, T2) [with T1 = unsigned int; T2 =
> unsigned int]: Assertion `x == y' failed.
>
>
> Aborted
>
> The example is compiled with gcc 5.2 and boost 1.60 (
> http://melpon.org/wandbox/permlink/QF1qyw5bWHKwyKJ8). Is there an error
> in my code? I would guess that transforming a range into a range of new
> objects of another type is quite common, so it should work. I am also
> curious why the warning is only emitted when compiling with optimizations.
>
> Best wishes,
> Jens
>
> --
> Jens Auer | CGI | Software-Engineer
> CGI (Germany) GmbH & Co. KG
> Rheinstraße 95 | 64295 Darmstadt | Germany
> T: +49 6151 36860 154
> jens.auer_at_[hidden]<mailto:jens.auer_at_[hidden]>
> Unsere Pflichtangaben gemäß § 35a GmbHG / §§ 161, 125a HGB finden Sie
> unter de.cgi.com/pflichtangaben<http://de.cgi.com/pflichtangaben>.
>
> CONFIDENTIALITY NOTICE: Proprietary/Confidential information belonging to
> CGI Group Inc. and its affiliates may be contained in this message. If you
> are not a recipient indicated or intended in this message (or responsible
> for delivery of this message to such person), or you think for any reason
> that this message may have been addressed to you in error, you may not use
> or copy or deliver this message to anyone else. In such case, you should
> destroy this message and are asked to notify the sender by reply e-mail.
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

-- 
Андрей Давыдов.

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk