After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 669128 - tests/test_lambda.cc does not compile
tests/test_lambda.cc does not compile
Status: RESOLVED FIXED
Product: libsigc++
Classification: Bindings
Component: tests
unspecified
Other Linux
: Normal normal
: ---
Assigned To: libsigc++ maintainer(s)
libsigc++ maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2012-01-31 18:58 UTC by Andris Pavenis
Modified: 2012-09-17 20:17 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch: Re-enable test_lambda in 'make check'. (4.14 KB, patch)
2012-03-18 17:47 UTC, Kjell Ahlstedt
accepted-commit_now Details | Review

Description Andris Pavenis 2012-01-31 18:58:35 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
Comment 1 Kjell Ahlstedt 2012-03-18 17:47:15 UTC
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
Comment 2 Murray Cumming 2012-03-19 09:04:11 UTC
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.
Comment 3 Murray Cumming 2012-03-19 09:07:57 UTC
>  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.
Comment 4 Kjell Ahlstedt 2012-03-19 15:35:19 UTC
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.
Comment 5 Murray Cumming 2012-09-17 20:17:19 UTC
(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 .