lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Integer overflow warnings in bourn_cast with clang


From: Greg Chicares
Subject: Re: [lmi] Integer overflow warnings in bourn_cast with clang
Date: Thu, 6 Apr 2017 20:23:51 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Icedove/45.6.0

On 2017-04-06 19:11, Vadim Zeitlin wrote:
> On Thu, 6 Apr 2017 18:35:03 +0000 Greg Chicares <address@hidden> wrote:
[...]
> GC> I've just pushed
> GC> a change that clarifies the error message in the way I believe you
> GC> recommended, e.g.:
> GC> 
> GC> Cast from 3.140000 [float] to 3 [long long] would not preserve value.
> 
>  This is definitely incomparably more useful, thank you!

I'm glad you expressed an opinion, because I've had that change sitting
in my "stash" directory for some time, but couldn't decide whether to
commit it or not.

Let me ask your opinion on another issue: conversion to bool.
  static_cast<int>(DBL_MAX);  // undefined behavior [conv.fpint/1]
  static_cast<bool>(DBL_MAX); // result is 'false' [conv.bool]
At the moment, bourn_cast rejects both, and I'm inclined to keep it that
way, but do you disagree?

The reason I ask is that I'm trying to summarize what bourn_cast is
supposed to do. One of its goals is to avoid all conversions that
constitute undefined behavior (at least, as far as possible--I'm not
sure we can guarantee that if floating point doesn't follow IEEE 754).
Strict value preservation can't be a goal if we allow
  bourn_cast<float>(ULL_MAX);
yet we've decided to disallow silent truncation
  bourn_cast<int>(2.71828);
so I think the best description is...

  Do what static_cast does, when its behavior is defined, iff the
  source value is within the target type's [lowest(), max()] range;
  throw otherwise. However, throw if floating-to-integral conversion
  would truncate, because that circumstance calls for rounding [this
  is the only intentional difference from boost::numeric_cast].

  Corollary: integral-to-integral conversion either preserves value
  or throws.

Then the present behavior of bourn_cast<bool> follows immediately.
I think that's reasonable because nobody writes static_cast<bool>
anyway:
  int xyz;
  if(xyz)  {do_something();}      // reasonable and common
  if(!xyz) {do_something_else();} // reasonable and common
  if(!static_cast<bool>(xyz)) {...} // downright weird
We want bourn_cast<bool> to be defined so that bourn_cast can convert
between any arithmetic types, and so that value_cast can convert
between any types for which it's defined. But we don't have to extend
the domain to values other than T(true) and T(false) for a general
arithmetic type T. Or am I missing something?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]