On Sun, Nov 25, 2018 at 3:05 PM Gavin Lambert via Boost < boost@lists.boost.org> wrote:
On 24/11/2018 08:58, Emil Dotchevski wrote:
I'm guessing you want an example where the explicit conversion is incorrect, and you want to use an implicit conversion even though you
get a
warning. Here:
unsigned f();
void g( int x ) { if( x < f() ) //warning C4018: '<': signed/unsigned mismatch { .... } }
So you change that to:
if( static_cast<unsigned>(x) < f() )
Then under refactoring both f and g get changed:
unsigned long f();
void g( long x ) { if( static_cast<unsigned>(x) < f() ) { .... } }
auto xu = std::make_unsigned_t<decltype(x)>(x); if (xu < f())
This expresses your intent of using the unsigned version of the parameter.
You probably mean auto xu = std::make_unsigned<decltype(x)>::type(x); This is similar to the implicit conversion, except it doesn't eliminate the other implicit conversion which will occur if the return type of f is of size greater than the size of x, which will likely earn you another warning. Therefore you probably want auto xu = std::make_unsigned<decltype(f())>::type(x); which seems equivalent to the implicit conversion sans the warning. You'll also need typename in a generic context. Fine. Do you think programmers actually write this to silence such warnings, rather than cast? Are you arguing that they should?
assert(x>=0);
That helps -- assuming that people actually check asserts, which isn't always the case.
Ironically, in my experience the warning police doesn't care about the assert, even though it will actually catch the bugs they're trying to defend against, while the warning, silenced with a cast, won't.