...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Safe Numerics |
Up until now, we've mostly focused on detecting when incorrect results are produced and handling these occurrences either by throwing an exception or invoking some designated function. We've achieved our goal of detecting and handling arithmetically incorrect behavior - but at cost of checking many arithmetic operations at runtime. It is a fact that many C++ programmers will find this trade-off unacceptable. So the question arises as to how we might minimize or eliminate this runtime penalty.
The first step is to determine what parts of a program might invoke
exceptions. The following program is similar to previous examples but uses a
special exception policy: loose_trap_policy
.
// Copyright (c) 2018 Robert Ramey // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <iostream> #include <boost/safe_numerics/safe_integer.hpp> #include <boost/safe_numerics/exception_policies.hpp> // include exception policies using safe_t = boost::safe_numerics::safe< int, boost::safe_numerics::native, boost::safe_numerics::loose_trap_policy // note use of "loose_trap_exception" policy! >; int main(){ std::cout << "example 81:\n"; safe_t x(INT_MAX); safe_t y(2); safe_t z = x + y; // will fail to compile ! return 0; }
Now,
any expression which might fail at runtime is flagged with a
compile time error. There is no longer any need for try/catch
blocks. Since this program does not compile, the library absolutely guarantees that no
arithmetic expression will yield incorrect results.
Furthermore, it is absolutely guaranteed that no
exception will ever be thrown. This is our original goal.
Now all we need to do is make the program compile. There are a couple of ways to achieve this.