Skip to content

<numeric>: gcd and lcm do not check for negative overflow in compile time #2300

@AlexGuteniev

Description

@AlexGuteniev

Describe the bug
When given the least possible signed integer value, gcd cannot make it positive, and returns a negative result.
According to [numeric.ops.gcd]/2, it is UB:

Preconditions: |m| and |n| are representable as a value of common_­type_­t<M, N>.
[Note 1: These requirements ensure, for example, that gcd(m, m)=|m| is representable as a value of type M. — end note]

According to [expr.const]/6 whereas language UB shouldn't compile, it is implementation-specific if library precondition violation compiles in constexpr context or not.

Since we are permitted do a favor and reject overflowing value, we should.

The same is for lcm, except that it should also check the result.

Command-line test case

#include <limits>
#include <numeric>
using namespace std;

auto test() {
    constexpr int x = numeric_limits<int>::lowest();
    constexpr int y = numeric_limits<int>::lowest();
    constexpr auto z = std::gcd(x, y);
    return z;
}

returns -1

Expected behavior
Don't compile

STL version

Version 17.0.0 Preview 6.0

Additional context
From this conversation https://discord.com/channels/737189251069771789/740318951766098012/902077925506039808

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSomething can be improvedfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions