static const bool is_modulo; | (until C++11) | |

static constexpr bool is_modulo; | (since C++11) |

The value of `std::numeric_limits<T>::is_modulo`

is `true`

for all arithmetic types `T`

that are possible to (until C++11)handle overflows with modulo arithmetic, that is, if the result of addition, subtraction, multiplication, or division of this type would fall outside the range `[min(), max()]`

, the value returned by such operation differs from the expected value by a multiple of `max()-min()+1`

.

| (since C++11) |

`T` | value of `std::numeric_limits<T>::is_modulo` |
---|---|

/* non-specialized */ | `false` |

`bool` | `false` |

`char` | implementation-defined |

`signed char` | implementation-defined |

`unsigned char` | `true` |

`wchar_t` | implementation-defined |

`char8_t` (C++20) | `true` |

`char16_t` (C++11) | `true` |

`char32_t` (C++11) | `true` |

`short` | implementation-defined |

`unsigned short` | `true` |

`int` | implementation-defined |

`unsigned int` | `true` |

`long` | implementation-defined |

`unsigned long` | `true` |

`long long` (C++11) | implementation-defined |

`unsigned long long` (C++11) | `true` |

`float` | `false` |

`double` | `false` |

`long double` | `false` |

Although the C++11 standard still says "On most machines, this is true for signed integers.", it is a defect and has been corrected. The exact wording changed from C++03 to C++11 in such a way that the `true`

value is no longer compatible with undefined behavior on signed integer overflow. Because of that, the implementations that rely on signed overflow being undefined (for optimization opportunities) now set `is_modulo`

to `false`

for signed integers. See for example GCC PR 22200.

Demonstrates the behavior of modulo types.

#include <iostream> #include <type_traits> #include <limits> template<class T> typename std::enable_if<std::numeric_limits<T>::is_modulo>::type check_overflow() { std::cout << "\nmax value is " << std::numeric_limits<T>::max() << '\n' << "min value is " << std::numeric_limits<T>::min() << '\n' << "max value + 1 is " << std::numeric_limits<T>::max()+1 << '\n'; } int main() { check_overflow<int>(); check_overflow<unsigned long>(); // check_overflow<float>(); // compile-time error, not a modulo type }

Possible output:

max value is 2147483647 min value is -2147483648 max value + 1 is -2147483648 max value is 18446744073709551615 min value is 0 max value + 1 is 0

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|

LWG 2422 | C++11 | `is_modulo` was required to `true` for signed integer types on most machines | required to be `false` for signed integer typesunless signed integer overflow is defined to wrap |

[static] | identifies integer types (public static member constant) |

[static] | identifies the IEC 559/IEEE 754 floating-point types (public static member constant) |

[static] | identifies exact types (public static member constant) |

© cppreference.com

Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.

https://en.cppreference.com/w/cpp/types/numeric_limits/is_modulo