C++ Logo

std-proposals

Advanced search

[std-proposals] Proposal: Integer division/remainder/division-remainder functions with exception throwing behavior

From: None <a1343922569_at_[hidden]>
Date: Wed, 30 Apr 2025 12:13:40 +0000
Hello everyone,
I would like to propose adding a set of integer division, remainder, and combined division-remainder functions to the C++ standard library that throw exceptions when the divisor is zero.
The motivation is that, in the current C++ standard, integer division and remainder operations with a zero divisor are defined as "undefined behavior" (UB). This design has several drawbacks:
1. ıPerformance considerations: To avoid UB with zero divisors, programmers must explicitly check if the divisor is zero, introducing conditional branches. In scenarios where the divisor is almost always non-zero, this leads to branch prediction failures, which may disrupt the pipeline in CPU and degrade the performance significantly.
2. Portability issues: Some performance-sensitive applications need to leverage CPU division-by-zero exception mechanisms to check the divisor, but this typically relies on non-standard system calls or inline assembly, severely impacting code portability.
3. Inconsistency with modern languages: Languages like Java and Python throw exceptions when dividing by zero, allowing developers to handle such cases elegantly through exception handling mechanisms rather than relying on UB.

Proposed features
To address these issues while maintaining backward compatibility, I propose adding the following (template) functions to the standard library (T can be any fundamental integer type, such as int64_t, uint64_t):

namespace std
{
    // Integer division that throws on zero divisor
    template<typename T>
    T div_with_exception(T dividend, T divisor);

    // Integer remainder that throws on zero divisor
    template<typename T>
    T rem_with_exception(T dividend, T divisor);

    // Computes both quotient and remainder, throws on zero divisor
    template<typename T>
    std::div_t<T> divrem_with_exception(T dividend, T divisor);

    // Specialized exception type
    class integer_division_by_zero : public std::exception
    {
    public:
        const char* what() const noexcept override;
    };
}

Technical details
1. These functions should support all built-in integer types and standard-defined integer type aliases (like int64_t, uint64_t).
2. The functions should follow the same semantics as existing integer division and remainder operators, with the only difference being that division by zero is not UB but throws a std::integer_division_by_zero exception.
3. Compilers should be able to apply the same optimizations to these functions as they do for integer division and remainder operators, such as bitwise shift or multiplication conversions for constant divisors, while ensuring exception behavior for zero divisors.
4. Implementation can leverage platform-specific CPU exception handling mechanisms without explicit divisor checking, for example:
    a. Directly using CPU division instructions.
    b. Catching hardware division-by-zero exceptions.
    c. Translating them to C++ exceptions.

Usage example
try {
    // No need for explicit check if b is zero
    uint64_t c = std::div_with_exception(a, b);
    std::cout << "Quotient: " << c << std::endl;
} catch (std::integer_division_by_zero const& e) {
    // Handle division by zero
    std::cout << "Division by zero!" << std::endl;
}


Compared to traditional methods, this approach provides better performance when the divisor is almost always non-zero, while making the code clearer.

Best regards.

Received on 2025-04-30 12:13:46