GNOME Bugzilla – Bug 669128
tests/test_lambda.cc does not compile
Last modified: 2012-09-17 20:17:19 UTC
File tests/test_lambda.cc does not compile. Perhaps this is result of complete disabling this test for a long time due to build failure on one target (it should perhaps be disabled for that target only by different means) Tested with different compilers: gcc-4.6.2 and gcc-3.4.6 on Fedora 16 gcc-4.1.2 on CentOS-5.6 g++ -DHAVE_CONFIG_H -I.. -I.. -Wall -g -O2 -MT test_lambda.o -MD -MP -MF .deps/test_lambda.Tpo -c -o test_lambda.o test_lambda.cc In file included from ../sigc++/adaptors/lambda/lambda.h:25:0, from test_lambda.cc:9: ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_deduce_result_type<sigc::arithmetic<sigc::multiplies>, T_arg1, T_arg2>::type sigc::lambda_action<sigc::arithmetic<sigc::multiplies> >::do_action(T_arg1, T_arg2) [with T_arg1 = sigc::reference_wrapper<int>, T_arg2 = int, typename sigc::lambda_action_deduce_result_type<sigc::arithmetic<sigc::multiplies>, T_arg1, T_arg2>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:552:19: instantiated from ‘typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type sigc::lambda_operator<T_action, T_type1, T_type2>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>&, T_action = sigc::arithmetic<sigc::multiplies>, T_type1 = sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_increment>, sigc::internal::lambda_select1>, T_type2 = int, typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ ../sigc++/adaptors/lambda/base.h:70:19: instantiated from ‘typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type sigc::internal::lambda_core<T_type, true>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>, T_type = sigc::lambda_operator<sigc::arithmetic<sigc::multiplies>, sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_increment>, sigc::internal::lambda_select1>, int>, typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ test_lambda.cc:74:65: instantiated from here ../sigc++/adaptors/lambda/operator.h:183:21: error: could not convert ‘(_A_1.sigc::reference_wrapper<T_type>::operator T_type& [with T_type = int]() * _A_2)’ from ‘int’ to ‘sigc::lambda_action_deduce_result_type<sigc::arithmetic<sigc::multiplies>, sigc::reference_wrapper<int>, int>::type {aka sigc::reference_wrapper<int>}’ ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_increment>, T_arg>::type sigc::lambda_action_unary<sigc::unary_arithmetic<sigc::pre_increment> >::do_action(T_arg) [with T_arg = sigc::reference_wrapper<int>&, typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_increment>, T_arg>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:788:19: instantiated from ‘typename sigc::lambda_operator_unary<T_action, T_type>::deduce_result_type<T_arg1>::type sigc::lambda_operator_unary<T_action, T_type>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>&, T_action = sigc::unary_arithmetic<sigc::pre_increment>, T_type = sigc::internal::lambda_select1, typename sigc::lambda_operator_unary<T_action, T_type>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ ../sigc++/adaptors/lambda/operator.h:552:19: instantiated from ‘typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type sigc::lambda_operator<T_action, T_type1, T_type2>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>&, T_action = sigc::arithmetic<sigc::multiplies>, T_type1 = sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_increment>, sigc::internal::lambda_select1>, T_type2 = int, typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ ../sigc++/adaptors/lambda/base.h:70:19: instantiated from ‘typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type sigc::internal::lambda_core<T_type, true>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>, T_type = sigc::lambda_operator<sigc::arithmetic<sigc::multiplies>, sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_increment>, sigc::internal::lambda_select1>, int>, typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ test_lambda.cc:74:65: instantiated from here ../sigc++/adaptors/lambda/operator.h:435:16: error: could not convert ‘++(& _Aa)->sigc::reference_wrapper<T_type>::operator T_type& [with T_type = int]()’ from ‘int’ to ‘sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_increment>, sigc::reference_wrapper<int>&>::type {aka sigc::reference_wrapper<int>}’ ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_decrement>, T_arg>::type sigc::lambda_action_unary<sigc::unary_arithmetic<sigc::pre_decrement> >::do_action(T_arg) [with T_arg = sigc::reference_wrapper<int>&, typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_decrement>, T_arg>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:788:19: instantiated from ‘typename sigc::lambda_operator_unary<T_action, T_type>::deduce_result_type<T_arg1>::type sigc::lambda_operator_unary<T_action, T_type>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>&, T_action = sigc::unary_arithmetic<sigc::pre_decrement>, T_type = sigc::lambda_operator_unary<sigc::unary_other<sigc::dereference>, sigc::lambda_operator_unary<sigc::unary_other<sigc::address>, sigc::internal::lambda_select1> >, typename sigc::lambda_operator_unary<T_action, T_type>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ ../sigc++/adaptors/lambda/operator.h:552:19: instantiated from ‘typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type sigc::lambda_operator<T_action, T_type1, T_type2>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>&, T_action = sigc::arithmetic<sigc::multiplies>, T_type1 = sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_decrement>, sigc::lambda_operator_unary<sigc::unary_other<sigc::dereference>, sigc::lambda_operator_unary<sigc::unary_other<sigc::address>, sigc::internal::lambda_select1> > >, T_type2 = int, typename sigc::lambda_operator<T_action, T_type1, T_type2>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ ../sigc++/adaptors/lambda/base.h:70:19: instantiated from ‘typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type sigc::internal::lambda_core<T_type, true>::operator()(T_arg1) const [with T_arg1 = sigc::reference_wrapper<int>, T_type = sigc::lambda_operator<sigc::arithmetic<sigc::multiplies>, sigc::lambda_operator_unary<sigc::unary_arithmetic<sigc::pre_decrement>, sigc::lambda_operator_unary<sigc::unary_other<sigc::dereference>, sigc::lambda_operator_unary<sigc::unary_other<sigc::address>, sigc::internal::lambda_select1> > >, int>, typename sigc::internal::lambda_core<T_type, true>::deduce_result_type<T_arg1>::type = sigc::reference_wrapper<int>]’ test_lambda.cc:78:77: instantiated from here ../sigc++/adaptors/lambda/operator.h:444:16: error: could not convert ‘--(& _Aa)->sigc::reference_wrapper<T_type>::operator T_type& [with T_type = int]()’ from ‘int’ to ‘sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_decrement>, sigc::reference_wrapper<int>&>::type {aka sigc::reference_wrapper<int>}’ ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_increment>, T_arg>::type sigc::lambda_action_unary<sigc::unary_arithmetic<sigc::pre_increment> >::do_action(T_arg) [with T_arg = sigc::reference_wrapper<int>&, typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_increment>, T_arg>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:435:21: warning: control reaches end of non-void function [-Wreturn-type] ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_deduce_result_type<sigc::arithmetic<sigc::multiplies>, T_arg1, T_arg2>::type sigc::lambda_action<sigc::arithmetic<sigc::multiplies> >::do_action(T_arg1, T_arg2) [with T_arg1 = sigc::reference_wrapper<int>, T_arg2 = int, typename sigc::lambda_action_deduce_result_type<sigc::arithmetic<sigc::multiplies>, T_arg1, T_arg2>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:183:27: warning: control reaches end of non-void function [-Wreturn-type] ../sigc++/adaptors/lambda/operator.h: In static member function ‘static typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_decrement>, T_arg>::type sigc::lambda_action_unary<sigc::unary_arithmetic<sigc::pre_decrement> >::do_action(T_arg) [with T_arg = sigc::reference_wrapper<int>&, typename sigc::lambda_action_unary_deduce_result_type<sigc::unary_arithmetic<sigc::pre_decrement>, T_arg>::type = sigc::reference_wrapper<int>]’: ../sigc++/adaptors/lambda/operator.h:444:21: warning: control reaches end of non-void function [-Wreturn-type] make[2]: *** [test_lambda.o] Error 1 make[2]: Leaving directory `/home/andris/Devel/gnome/libsigc++/libsigc++2/tests' make[1]: *** [check-am] Error 2 make[1]: Leaving directory `/home/andris/Devel/gnome/libsigc++/libsigc++2/tests' make: *** [check-recursive] Error 1
Created attachment 210052 [details] [review] patch: Re-enable test_lambda in 'make check'. I've compiled with gcc version 4.6.1 under Ubuntu 11.10. All the compiler error messages come from these two lines: std::cout << "((++_1)*2)(ref(a)): " << ((++_1)*2)(sigc::ref(a)); std::cout << "((--(*(&_1)))*2)(ref(a)): " << ((--(*(&_1)))*2)(sigc::ref(a)); The compiler can't handle sigc::ref(a) in lambda functions. I checked part of the history of libsigc++ in git. Some interesting changes: 2003-08-31: These two template specializations were added to sigc++/type_traits.h: template <class T_type> struct type_trait<reference_wrapper<T_type> > template <class T_type> struct type_trait<const_reference_wrapper<T_type> > 2003-09-03: sigc::ref(a) was added to test_lamdba.cc. At that time test_lamdba.cc had been enabled (included in 'make check') for some time. 2005-01-19: test_lambda.cc was disabled with this comment added to tests/Makefile.am: # Disabled: test_lambda - The Tru64 compiler can't build this when not using # -std strict_ansi -model ansi, so let's not worry about it. Presumably other compilers could compile test_lambda.cc at that time. 2005-05-10: The two template specializations for reference_wrapper were removed from sigc++/type_traits.h, with this comment in ChangeLog: "The reference_wrapper class is only used in bound_argument.h. Put correct but unused code under #if 0." (The last sentence is wrong. The code was removed, and not put under #if 0.) Probably this removal ended the possibility to compile test_lambda.cc, but since that test had been disabled earlier, no one noticed it. When I re-inserted those template specializations, gcc can compile test_lambda.cc, and the built executable can be executed. _But_ with those template specializations in place, tests/test_bind.cc does not compile. A sigc::ref() can't be bound. That's of course unacceptable. At the same time as the template specializations were removed from type_traits.h, many other files were changed. Obviously it's not possible to undo only the changes in type_traits.h. And I suppose there was a good reason for doing all those changes. The attached patch "fixes" this bug by commenting out the two lines that don't compile, and enabling test_lambda.cc in 'make check'. Some questions need answers before this patch is pushed. 1. Is this an acceptable way to fix this bug? I can't find anything mentioned about sigc::ref() in lambda expressions in the documentation. It has probably been impossible since May 2005. 2. If the Tru64 compiler is still supported, someone with access to that compiler should check if it can compile test_lambda.cc. 3. Will we continue to support lambda functions in libsigc++? For how long? Now that the C++11 standard specifies lambda functions, is there a good reason for using any other kind of lambda functions when C++11 compilers have become widely available? http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B
Review of attachment 210052 [details] [review]: Sure. Please push this, but please add TODO in those comments, and add a full URL to the bug report rather than just the bug number.
> If the Tru64 compiler is still supported, someone with access to that > compiler should check if it can compile test_lambda.cc. The Tru64 compiler is supported as much as people care about it, which probably isn't much recently. Don't worry about it too much. > Will we continue to support lambda functions in libsigc++? For how long? Now that the C++11 standard specifies lambda functions I'm all for deprecating anything that is now provided by regular C++. It's obviously easier to maintain libsigc++ when it is smaller. Any examples or tests, if any, would have to be updated to show people how to change their code.
Pushed with some comments changed. > please add TODO in those comments I'm not sure what you wanted me to add. If you don't like my added comments, please change, or tell me how to change. > I'm all for deprecating anything that is now provided by regular C++. I can file a bug, suggesting that libsigc++'s lambda functions shall be deprecated. The advanced use of C++ templates in the lambda functions is a bit beyond my knowledge of templates, and I get the impression that no one is eager to fix lambda function bugs.
(In reply to comment #4) > Pushed with some comments changed. > > > please add TODO in those comments > > I'm not sure what you wanted me to add. If you don't like my added comments, > please change, or tell me how to change. It looks fine now. > > I'm all for deprecating anything that is now provided by regular C++. > > I can file a bug, suggesting that libsigc++'s lambda functions shall be > deprecated. The advanced use of C++ templates in the lambda functions is a bit > beyond my knowledge of templates, and I get the impression that no one is eager > to fix lambda function bugs. For the record, you filed that as bug #672555 .