I am using boost::phoenix lambda functions and I am observing some weird behaviours when compiling with optimizations (-O3). The first issue is that compiling the following piece of code Compiling: const float x = 1.0f; const float y = 1.0f; std::cout << (arg1+arg2)(x,y); with g++ -Wall gives the warning: boost_1_46_0/boost/spirit/home/phoenix/operator/arithmetic.hpp:74:5: warning: returning reference to temporary And I suspect a bug in the project I am working on is a consequence of this. It is as if a boost::for_each( rng, lambda_fun ) was optimized out. I have opened a ticket on this issue: https://svn.boost.org/trac/boost/ticket/5190 I suspect the issue comes from the type deduction inside phoenix. I first discovered the issue with boost 1.45.0, but it still here in 1.46.0. The other issue I am facing is similar. Consider the following code: namespace bp = boost::phoenix; using boost::phoenix::arg_names::arg1; int i=0; int a[] = {0}; template<class UnaryFunction> inline void foo( UnaryFunction fun ) { fun(i); } int main() { foo( bp::ref(a)[arg1]++ ); std::cout << a[0] << " "; (bp::ref(a)[arg1]++)(i); std::cout << a[0] << "\n"; } Compiled without optimizations, it corectly prints: 1 2 Whereas compiled with g++-4.5.1 -O3 with boost 1.45.0, it prints: 0 1, as if the first lambda invocation was removed. The issue disappears if I use g++-4.4 or boost 1.46.0. I tracked the changes between boost 1.45.0 and 1.46.0, and it seems related to https://svn.boost.org/trac/boost/changeset/66411 applying the part of the changeset concerning: fusion/support/detail/is_mpl_sequence.hpp fusion/support/is_sequence.hpp fusion/support/sequence_base.hpp to boost 1.45.0 fixes the issue, but I can't see how this is related to the bug I observed. Is it a compiler bug, a phoenix bug or a mistake in my code ? Thanks, nicolas
On 2/24/2011 11:05 PM, Nicolas Savoire wrote:
I am using boost::phoenix lambda functions and I am observing some weird behaviours when compiling with optimizations (-O3).
The first issue is that compiling the following piece of code
Compiling: const float x = 1.0f; const float y = 1.0f; std::cout<< (arg1+arg2)(x,y);
with g++ -Wall gives the warning: boost_1_46_0/boost/spirit/home/phoenix/operator/arithmetic.hpp:74:5: warning: returning reference to temporary
And I suspect a bug in the project I am working on is a consequence of this. It is as if a boost::for_each( rng, lambda_fun ) was optimized out. I have opened a ticket on this issue: https://svn.boost.org/trac/boost/ticket/5190 I suspect the issue comes from the type deduction inside phoenix. I first discovered the issue with boost 1.45.0, but it still here in 1.46.0.
The other issue I am facing is similar. Consider the following code:
namespace bp = boost::phoenix; using boost::phoenix::arg_names::arg1;
int i=0; int a[] = {0};
template<class UnaryFunction> inline void foo( UnaryFunction fun ) { fun(i); }
int main() { foo( bp::ref(a)[arg1]++ ); std::cout<< a[0]<< " ";
(bp::ref(a)[arg1]++)(i); std::cout<< a[0]<< "\n"; }
Compiled without optimizations, it corectly prints: 1 2 Whereas compiled with g++-4.5.1 -O3 with boost 1.45.0, it prints: 0 1, as if the first lambda invocation was removed.
The issue disappears if I use g++-4.4 or boost 1.46.0. I tracked the changes between boost 1.45.0 and 1.46.0, and it seems related to https://svn.boost.org/trac/boost/changeset/66411 applying the part of the changeset concerning: fusion/support/detail/is_mpl_sequence.hpp fusion/support/is_sequence.hpp fusion/support/sequence_base.hpp to boost 1.45.0 fixes the issue, but I can't see how this is related to the bug I observed. Is it a compiler bug, a phoenix bug or a mistake in my code ?
Could you try with Phoenix3 (on going mini-review) and see if this is an issue? I can try and investigate with Phoenix2 if you can provide a minimal cpp test case that I can run. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
On Friday, February 25, 2011 01:12:51 am Joel de Guzman wrote:
On 2/24/2011 11:05 PM, Nicolas Savoire wrote:
I am using boost::phoenix lambda functions and I am observing some weird behaviours when compiling with optimizations (-O3).
The first issue is that compiling the following piece of code
Compiling: const float x = 1.0f; const float y = 1.0f; std::cout<< (arg1+arg2)(x,y);
with g++ -Wall gives the warning: boost_1_46_0/boost/spirit/home/phoenix/operator/arithmetic.hpp:74:5: warning: returning reference to temporary
And I suspect a bug in the project I am working on is a consequence of this. It is as if a boost::for_each( rng, lambda_fun ) was optimized out. I have opened a ticket on this issue: https://svn.boost.org/trac/boost/ticket/5190 I suspect the issue comes from the type deduction inside phoenix. I first discovered the issue with boost 1.45.0, but it still here in 1.46.0.
The other issue I am facing is similar. Consider the following code:
namespace bp = boost::phoenix; using boost::phoenix::arg_names::arg1;
int i=0; int a[] = {0};
template<class UnaryFunction> inline void foo( UnaryFunction fun ) {
fun(i);
}
int main() {
foo( bp::ref(a)[arg1]++ ); std::cout<< a[0]<< " ";
(bp::ref(a)[arg1]++)(i); std::cout<< a[0]<< "\n";
}
Compiled without optimizations, it corectly prints: 1 2 Whereas compiled with g++-4.5.1 -O3 with boost 1.45.0, it prints: 0 1,
as if the first lambda invocation was removed.
The issue disappears if I use g++-4.4 or boost 1.46.0. I tracked the changes between boost 1.45.0 and 1.46.0, and it seems related to https://svn.boost.org/trac/boost/changeset/66411 applying the part of the changeset concerning: fusion/support/detail/is_mpl_sequence.hpp fusion/support/is_sequence.hpp fusion/support/sequence_base.hpp to boost 1.45.0 fixes the issue, but I can't see how this is related to the bug I observed. Is it a compiler bug, a phoenix bug or a mistake in my code ?
Could you try with Phoenix3 (on going mini-review) and see if this is an issue? I can try and investigate with Phoenix2 if you can provide a minimal cpp test case that I can run.
Regards,
I attached to this email two minimal test cases. Both fail with boost 1.45.0 and g++-4.5.1 with compilation flags -O3. My gcc version is : Using built-in specs. COLLECT_GCC=g++-4.5 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.5.1/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.5.1-7ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-4.5/README.Bugs -- enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.5 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix -- with-gxx-include-dir=/usr/include/c++/4.5 --libdir=/usr/lib --enable-nls -- with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable- libstdcxx-time=yes --enable-plugin --enable-gold --with-plugin-ld=ld.gold -- enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic -- enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu -- target=x86_64-linux-gnu Thread model: posix gcc version 4.5.1 (Ubuntu/Linaro 4.5.1-7ubuntu2) They both pass if I use g++-4.4. Second test case pass with g++-4.5.1 and boost 1.46.0, but as I said in my previous mail, I don't understand how the changes in boost 1.46.0 contributed to solve the issue. First test case still fails with g++-4.5.1 and boost 1.46.0. I was able to fix the issue by adding float to the handled types in boost/spirit/home/phoenix/detail/type_deduction.hpp, in a manner similar to bool,int,uint and double. The good news is that both test cases pass with phoenix v3 ! But the inclusion of phoenix v3 in boost is still months away... Thanks for your help, nicolas
participants (2)
-
Joel de Guzman
-
Nicolas Savoire