gpt4 book ai didi

c++ - 从常量表达式中有符号整数的溢出中删除未定义的行为?

转载 作者:行者123 更新时间:2023-12-05 08:28:53 24 4
gpt4 key购买 nike

编辑在实际示例中,负溢出似乎有可能发生,我还添加了一个示例来演示那里的错误

我正在使用 C++20 并尝试将依赖于 Java 和 C# 中有符号整数溢出的库转换为 C++ 代码。我还试图生成它在编译时使用的表,并允许这些表在编译时可用。

在我的代码中,我在引用代码时遇到错误,看起来像这样(重现错误的最小示例,解决方案也将解决我的问题):

#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;
}

https://godbolt.org/z/TvM45vd8d

负溢出版本

#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;
}

https://godbolt.org/z/7zoE9r18E

我得到 12905529061151879018 超出了 long long 和 -12905529061151879018 分别表示的范围。

我知道这里不允许未定义的行为,我也认识到 GCC 和 MSVC 不会在这里出错,你可以放一个标志让 clang 编译它。但是我应该怎么做才能实际上解决这个问题而不用切换编译器或应用标志来忽略无效的 constexpr?

有什么方法可以定义我期望并希望发生的行为吗?

最佳答案

有符号整数在您可以命名的任何实现中都具有二进制补码布局。它也保证使用两个's 自 C++20 以来的补码布局。

这意味着您可以对无符号 整数执行数学运算,并获得与您希望有符号 整数执行的操作相匹配的明确定义的溢出行为。

#include <iostream> 
#include <bit>

constexpr auto foo(){
std::uint64_t a = 2;
std::uint64_t very_large_constant = 0x598CD327003817B5L;
std::uint64_t x = a * very_large_constant;
return static_cast<std::int64_t>(x);
}

关于c++ - 从常量表达式中有符号整数的溢出中删除未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73602012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com