2
votes

The following example results in:

boost/bind/bind.hpp:882: error: returning reference to temporary

if compiled with -std=c++0x.

If built without -std=c++0x flag, no warnings occur. It appears boost is trying to use c++11 rvalues here even though gcc 4.4 doesn't fully support it. Thanks in advance!

gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)

Full build line: g++ -std=c++0x -Wall -Werror -I/pathtoboost/include main.cpp -o bind

#include <boost/function.hpp>
#include <boost/bind.hpp>

#include <iostream>

int foo( int a )
{
    std::cout << "a: " << a << std::endl;
    return a;
}

int main( int argc, char** argv )
{
    foo( 5 );
    boost::function< int( int ) > bfoo = boost::bind( foo, _1 );
    bfoo( 10 );
    return 0;
}

Full build error (warnings):

cc1plus: warnings being treated as errors
In file included from /boost/include/boost/bind.hpp:22,
                 from main.cpp:2:
/boost/include/boost/bind/bind.hpp: In member function ‘A1&& boost::_bi::rrlist1<A1>::operator[](boost::arg<1> (*)()) const [with A1 = int]’:
/boost/include/boost/bind/bind.hpp:249:   instantiated from ‘R boost::_bi::list1<A1>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = int, F = int (*)(int), A = boost::_bi::rrlist1<int>, A1 = boost::arg<1>]’
/boost/include/boost/bind/bind.hpp:1306:   instantiated from ‘typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&&) [with A1 = int, R = int, F = int (*)(int), L = boost::_bi::list1<boost::arg<1> >]’
/boost/include/boost/function/function_template.hpp:138:   instantiated from ‘static R boost::detail::function::function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = boost::_bi::bind_t<int, int (*)(int), boost::_bi::list1<boost::arg<1> > >, R = int, T0 = int]’
/boost/include/boost/function/function_template.hpp:925:   instantiated from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = boost::_bi::bind_t<int, int (*)(int), boost::_bi::list1<boost::arg<1> > >, R = int, T0 = int]’
/boost/include/boost/function/function_template.hpp:716:   instantiated from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<(! boost::is_integral::value), int>::type) [with Functor = boost::_bi::bind_t<int, int (*)(int), boost::_bi::list1<boost::arg<1> > >, R = int, T0 = int]’
/boost/include/boost/function/function_template.hpp:1061:   instantiated from ‘boost::function<R(T0)>::function(Functor, typename boost::enable_if_c<(! boost::is_integral::value), int>::type) [with Functor = boost::_bi::bind_t<int, int (*)(int), boost::_bi::list1<boost::arg<1> > >, R = int, T0 = int]’
main.cpp:15:   instantiated from here
/boost/include/boost/bind/bind.hpp:882: error: returning reference to temporary
make: *** [all] Error 1
1
Remember that just because no warnings are emitted doesn't mean that warnings ought not be emitted. - Jesper Juhl
@JesperJuhl very good remark. Worse still, compilers aren't required to give any diagnostics on most things. It is strictly a best-effort thing - sehe
@sehe actually, it can be extremely difficult for compilers to emit many warnings that you'd find obvious on the surface, due to the way optimizations interact and the information lost between the frontend parsing youf code and the intermediate representation the optimizer sees. - Jesper Juhl
It's high time that you upgrade to the 6 year old standard (2011). I don't expect boost to support the 2003 or 1997 standards, but hope they will soon support the 2014 and 2017 standards ... - Walter

1 Answers

1
votes

I've run your code with GCC 4.4 (CentOS 6) with Boost 1.41(bundled in CentOS) and Boost 1.64(Latest). Your code works without any problem.

Maybe You mixed boost things and std things?

boost::function<int(int)> bfoo = boost::bind(foo, boost::placeholders::_1); // #1 works
boost::function<int(int)> bfoo = boost::bind(foo, _1); // #2 _1 is from boost -> works
std::function<int(int)> bfoo = std::bind(foo, std::placeholders::_1); // #3 works

std::function<int(int)> bfoo = std::bind(foo, _1); // #4 not work
boost::function<int(int)> bfoo = boost::bind(foo, std::placeholders::_1); #5 not work