Reputation: 8727
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?
Upvotes: 1
Views: 1047
Reputation: 238461
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.
Upvotes: 1
Reputation: 15951
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…
Upvotes: 0
Reputation: 155714
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. forunsigned int
, adding one toUINT_MAX
gives0
, and subtracting one from0
givesUINT_MAX
.
Similarly, standard library modules rarely use it:
The only standard library components that throw this exception are
std::bitset::to_ulong
andstd::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
throwsstd::overflow_error
ifboost::math::policies::throw_on_error
is enabled (the default setting).
Upvotes: 3
Reputation: 6131
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.
Upvotes: 2