boostorg / boostorg/safe_numerics
Compile-time range checks differ from run-time checks (one fails, the other passes)
- Dominant language
- C++
- Stars
- 222
- Forks
- 46
- PR merge metrics
- No merged PRs in 30d
Description
Hello. I work in the European Space Agency, and have experience with the kinds of checks done by Ada and SPARK - and since I just met "safe_numerics", I did a quick test of the library with the following code:
#include
#include
#include
#include
#include
using namespace boost::safe_numerics;
using safe_t = safe_signed_range<
0, 10,
native, // C++ type promotion rules work OK for this example
#ifdef COMPILE_TIME
loose_trap_policy // catch problems at compile time
#else
loose_exception_policy // catch problems at run-time
#endif
>;
template
#ifdef COMPILE_TIME
using const_safe_t = safe_signed_literal;
#else
using const_safe_t = safe_signed_literal;
#endif
safe_t f(safe_t x)
{
// fails to compile when we "gcc -DCOMPILE_TIME" - which is good! Adding 3 indeed drives us out of range
// return x + 3;
// fails to compile with "gcc -DCOMPILE_TIME". Why?
return (const_safe_t<10>() - x) / const_safe_t<2>();
}
int main()
{
for(safe_t i=0; i<10; i++) {
std::cout << f(i) << std::endl;
}
std::cout << f(10) << std::endl;
}
As the comments suggest, function `f` fails to compile when we enable compile-time checks (i.e. the `loose_trap_policy`) - but I don't see why.... `10-x` doesn't change the range (it remains 0..10 inclusive) and dividing by two gives a range from 0 to 5.
To verify I am not missing something obvious, when compiling without `-DCOMPILE_TIME`, we use the run-time checks - and `main` goes through the entire range, without triggering a run-time exception (and prints the expected outputs).
Is this a bug?
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the discrepancy using the example in the issue, starting with safe_integer_range.hpp, safe_integer_literal.hpp, and exception_policies.hpp. Compare the compile-time and run-time handling of f(safe_t x), especially the expression (const_safe_t<10>() - x) / const_safe_t<2>(). Done means explaining whether the differing outcomes are expected and aligning them if this is a bug.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100