On 28.03.2018 14:48, Christian Henning via Boost wrote:
Thank you Andrey!
With -ftrapv the code crashes at this point:
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 #1 0x00007ffff7490f5d in __GI_abort () at abort.c:90 #2 0x00007ffff783b2d8 in __addvsi3 () from /lib/x86_64-linux-gnu/libgcc_s .so.1 #3 0x00005555555548a9 in boost::gil::detail::channel_co nvert_to_unsigned<int>::operator() (this=<optimized out>, x=<optimized out>) at ./boost/gil/channel_algorithm.hpp:332 #4 boost::gil::channel_converter
::operator() (this=<optimized out>, src=@0x555555755014: 2147483647) at ./boost/gil/channel_algorithm. hpp:368 #5 boost::gil::channel_convert (src=@0x555555755014: 2147483647) at ./boost/gil/channel_algorithm.hpp:377 #6 main (argc=<optimized out>, argv=<optimized out>) at test_gil.cpp:32 channel_algorithm.hpp:332 is this line:
type operator()(bits32s x) const { return static_cast<bits32>(x+(1<<31)); }
This shift is UB because it overflows (until C++17, I think?). The addition will also overflow unless x is 0.
I would suggest casting to unsigned first and then performing the math.
I assume this is what you meant:
template <> struct channel_convert_to_unsigned<bits32s> : public std::unary_function
{ typedef bits32 type; type operator()(bits32s x) const { uint32_t a = static_cast (x); a += (1 << 31); return static_cast<bits32>(a); } };
Or simply replace `static_cast<bits32>(x+(1<<31))` by `static_cast<bits32>(x)+(1<<31)` (i.e., cast `x` rather than the full expression). Stefan -- ...ich hab' noch einen Koffer in Berlin...