c++ – Remove undefined behavior from overflow of signed integers in constant expressions?

EDIT In the actual example, it appears possible that negative overflow can happen, I’ve also added an example to demonstrate the error there

I’m using C++20 and trying to convert a library which relies on signed integer overflow in Java and C# into C++ code. I’m also trying to generate the tables it uses at compile time, and allow those to be available at compile time.

In my code I get errors in reference to code that looks like this (Minimal example to reproduce the error, the solution to this will solve my problem as well):

#include <iostream> 

constexpr auto foo(){
    std::int64_t a = 2; 
    std::int64_t very_large_constant = 0x598CD327003817B5L; 
    std::int64_t x = a * very_large_constant; 
    return x; 
}
 
int main(){
    std::cout << foo() << std::endl; 
    return 0; 
}

godbolt.org/z/TvM45vd8d

Negative overflow version

#include <iostream> 

constexpr auto foo(){
    std::int64_t a = -2; 
    std::int64_t very_large_constant = 0x598CD327003817B5L; 
    std::int64_t x = a * very_large_constant; 
    return x; 
}
 
int main(){
    std::cout << foo() << std::endl; 
    return 0; 
}

godbolt.org/z/7zoE9r18E

I get 12905529061151879018 is out side of range representable by long long and -12905529061151879018 respectively.

I understand that undefined behavior here is not allowed, I also recognize that GCC and MSVC do not error here, and you can put a flag to make clang compile this anyway. But what am I supposed to do to actually solve this issue with out switching compilers or applying the flag to ignore invalid constexpr?

Is there some way I can define the behavior I expect and want to happen here?

Read more here: Source link