|
Boost : |
Subject: Re: [boost] Is there interest in portable integer overflow detection, with policy based handling?
From: Ben Robinson (cppmaven_at_[hidden])
Date: 2012-02-23 23:33:35
On Thu, Feb 23, 2012 at 1:35 AM, Vicente J. Botet Escriba <
vicente.botet_at_[hidden]> wrote:
> Hi,
>
> I've found this use of METAASSERT that trouble my understanding
>
> // Prevent implicit conversion from one verified type to another
> // on assignment via operator T() on the right-hand-side.
> template <class R>
> verified_int(R const prevented) {
> BOOST_METAASSERT_MSG(sizeof(R) == 0, CANNOT_CONSTRUCT_FROM_A_**
> DIFFERENTLY_TYPED_VERIFIED_**INT, (R));
> }
>
>
> This doesn't prevent the implicit conversion, but makes it fail. This mean
> that if I have a function f overloaded with verified_int<X> and type
> ConvertibleFromR
>
> void f(verified_int<X>);
> void f(ConvertibleFromR);
>
> the call
>
> R r;
> f(r);
>
> will result on ambiguous resolution.
>
> I will explain the rational behind the implementation choices of the
binary math operators for VerifiedInt. When performing multiple operations
(let's take addition for example), the order of operations is important.
Compare:
verified_uint8_t a = 250;
verified_uint8_t b = a - 50 + 50;
verified_uint8_t c = a + 50 - 50;
Clearly computing b will not cause an overflow, but computing c will. The
order of operations is left to right. If the policy is to saturate, b will
equal 250, and c will equal 205.
VerifiedInts are also implicitly convertible to their underlying data
type. This presents a detection problem when the non-verified int is on
the LHS of a math operation. Take:
verified_uint8_t a = 250;
verified_uint8_t b = 50 + a;
Since a is implicitly convertable to a uint8_t, the compiler will perform
this conversion implicitly, and the result will be an undetected overflow.
It is for this reason, that I have supplied binary math operators where
only the RHS is a verified_int, and I have statically asserted them to
cause a compiler error. If the user wants to write such an expression,
they can statically cast 'a' to a uint8_t.
> I guess that as verifier_int is templated with a policy, the detection
> mechanism should be public, and so it should appear in a public file and
> not inside the detail directory.
>
> I can move the detection header file out of the detail directory, if that
seems more logical. You are correct, policy authors will need to include
and use it directly. I'll incorporate that feedback.
> I don't know if the rational to have on each overflow policy almost all
> the operation logic is due to performance constraints.
> Have you considered an overflow policy that contains only the action to do
> when there is an overflow?
>
I chose to allow the policy author to make a single function call to
determine if overflow has occured, and provide no restrictions on
implementing the resulting behavior. The policy author not only has access
to the type of overflow, but both values in the case of a math operation,
which would permit creating a periodic policy for example. Or a policy
could be created which only checks assignment, and has no run-time cost for
the math operations, etc... If more structure is desired, I could provide
it, but felt the trade-off wasn't worth it, considering I simplified the
detection logic to a single function call, provided in a single header.
Thank you,
Ben Robinson
>
> Best,
> Vicente
>
>
>
>
>
> ______________________________**_________________
> Unsubscribe & other changes: http://lists.boost.org/**
> mailman/listinfo.cgi/boost<http://lists.boost.org/mailman/listinfo.cgi/boost>
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk