1

I tried a simple code and found that integers variables are not overflowing instead it seems that latest C++ compiler has introduced a new functionality related to POD datatypes - if the variable crosses its max value, its values are restart from 0:

#include <iostream>
#include <cstdint>
#include <stdexcept>

int main()
{
try
{
for (uint8_t idx = 254 ;  ; idx++)
{
std::cout << unsigned(idx) << std::endl;
}
}
catch(std::overflow_error e)
{
std::cout << "Error" << std::endl;
}
}

When I run the code the exception code is never executed - but is this the desired behavior?

1
  • 1
    You will find that the handling of low-level stuff like this lies underneath C++ and does not throw exceptions, at least not exceptions in the C++ sense. For example division by zero is undefined behaviour, not an exception. Typically what happens with division by zero with integers is you get a floating point exception (Sounds really silly for integer math, huh?) that is NOT a C++ exception and cannot be caught with try/catch. Commented Feb 27, 2019 at 23:58

4 Answers 4

4

Almost nothing throws std::overflow_error; overflow of unsigned values is already defined in the language standard to wrap around to 0, it's not considered an "exceptional" case, so no exception will ever be thrown for plain unsigned integer math. Per cppreference docs on integer arithmetic overflow:

Unsigned integer arithmetic is always performed modulo 2n where n is the number of bits in that particular integer. E.g. for unsigned int, adding one to UINT_MAX gives ​0​, and subtracting one from ​0​ gives UINT_MAX.

Similarly, standard library modules rarely use it:

The only standard library components that throw this exception are std::bitset::to_ulong and std::bitset::to_ullong.

The mathematical functions of the standard library components do not throw this exception (mathematical functions report overflow errors as specified in math_errhandling). Third-party libraries, however, use this. For example, boost.math throws std::overflow_error if boost::math::policies::throw_on_error is enabled (the default setting).

Sign up to request clarification or add additional context in comments.

Comments

2

That is the behavior for unsigned types, according to the standard:

Standard 6.7.1/4

Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.

Which inspires the footnote:

This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

Comments

1

it seems that latest C++ compiler has introduced a new functionality

No. This is how C++ has always been specified.

if the variable crosses its max value, its values are restart from 0

If an unsigned integer result of a calculation is not representable by the type, then the result will instead be the representable value that is congruent with the mathematical result modulo 2n where n is the number of bits in the representation (i.e. congruent with the largest representable value + 1).

In other words, (largest representable unsigned integer + 1) is 0, just like you observed.

Note that this rule does not apply to signed integers. Overflowing a signed integer results in undefined behaviour.

P.S. No operation on a fundamental type is specified to throw an exception. Most of the standard library functions don't throw std::overflow_error either.

2 Comments

"largest representable unsigned integer + 1 is 0," - I understand you wanted to state the minimum?
@Programmer 0 is the minimum value representable by unsigned integer types.
0

unsigned int does not overflow or underflow, that's the core difference between signed and unsigned types in C++. unsigned types behave according to modulo arithmetic (i.e., they "wrap around") [basic.fundamental]/4. If you want to provoke an integer overflow, use a signed integer type. But even then, an integer overflow does not throw an exception but just lead to undefined behavior

2 Comments

A minor detail: an integer overflow is not required to throw an exception. As you say, the behavior is undefined. It could throw an exception.
you are technically correct—the best kind of correct… 😉

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.