Skip to content

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

Description

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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