【发布时间】:2014-08-22 04:07:38
【问题描述】:
假设这个世界上所有的数字都是正整数,它们可以用 uintX_t C++ 类型来表示。
让我们考虑下一个将 std::string 转换为数字的很棒的代码:
#include <string>
#include <cstdint>
#include <iostream>
template <typename T>
T MyAwsomeConversionFunction(const std::string& value)
{
T result = 0;
for(auto it = value.begin(); it != value.end() && std::isdigit(*it); ++it)
{
result = result * 10 + *it - '0';
}
return result;
}
int main(int argc, const char * argv[])
{
std::cout<<MyAwsomeConversionFunction<uint16_t>("1234")<<std::endl;
std::cout<<MyAwsomeConversionFunction<uint16_t>("123456")<<std::endl;
return 0;
}
如您所见,此函数存在多个错误,但我对特定的一个感兴趣:如何检测我的类型何时不足以包含该值(例如第二次转换调用)并避免 UB制作result = result * 10 + *it - '0';。我想知道该操作在进行之前是否会超过T 的最大值。这可能吗?
编辑:请查看Is signed integer overflow still undefined behavior in C++? 以获取有关 UB 关于 C++ 算术运算的更多信息。当结果溢出时,我想避免执行result = result * 10 + *it - '0'; 行。在答案中,该行仍在执行...
EDIT2:我在这里找到了答案:How to detect integer overflow?
EDIT3:接受的答案适用于签名类型。对于无符号类型 Cheers 和 hth。 - Alf 的答案是正确的。
【问题讨论】:
-
请注意,标准库有even more awesome code,它将检测溢出并抛出异常。
标签: c++ undefined-behavior numeric-conversion