c++ - 为什么 static_cast 减法会溢出?

标签 c++ static-cast size-type

据我了解,当 s2 较大时,s1.size() - s2.size() 会下溢,因为它是 unsigned 的减法。 为什么将它们转换为 int 不会导致整数减法? 为什么转换整个事情会给我正确的结果?我期望它评估括号内的内容,然后下溢,这将给出一个大数字,然后转换为 int 不会产生任何影响。我错过了什么?

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;

bool isShorter(const string &s1, const string &s2) {
    return (static_cast<int>(s1.size()) - s2.size() < 0) ? true : false; // underflows
    //return (static_cast<int>(s1.size() - s2.size()) < 0) ? true : false; // this works

}
int main() { 
    string s, t;
    getline(cin, s);
    getline(cin, t);
    cout << "s: " << s << endl;
    cout << "t: " << t << endl;
    cout << "printing shorter string of the two..." << endl;
    cout << ((isShorter(s, t)) ? s : t) << endl;
}

最佳答案

当你这样做时

static_cast<int>(s1.size()) - s2.size()

您转换s1.size()int然后当你减去s2.size()时由此可知int提升为与 s2.size() 相同的类型然后将其减去。这意味着您仍然需要进行无符号整数减法,并且由于它永远不会是负数,因此它会环绕到更大的数字。这和做s1.size() - s2.size()没有什么不同。 .

你也有同样的事情

static_cast<int>(s1.size() - s2.size())

还有可能有符号整数溢出的额外好处,这是未定义的行为。您仍在进行无符号整数减法,因此如果 s1小于 s2比你绕到一个大数字。

您需要做的是将 s1.size() 都转换为和s2.size()转换为有符号整数类型以获得有符号整数减法。这可能看起来像

static_cast<ptrdiff_t>(s1.size())  - static_cast<ptrdiff_t>(s2.size())

现在如果 s1.size() 你实际上会得到一个负数小于s2.size() .


需要注意的是,所有这些都可以通过使用小于运算符来避免。您的函数可以重写为

bool isShorter(const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}

恕我直言,这更容易阅读和理解。

关于c++ - 为什么 static_cast 减法会溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42700609/

相关文章:

c++ - 具有非均匀缩放的 3x3 矩阵旋转

c++ - 对重载函数的模糊调用

c++ - static_cast 抛出错误,但 C 风格的转换有效

c++ - C++ 中的 vector <int>::size_type

java - 如何访问 c.str() 内容?

c++ - 如何使 c++ fstream 类引用在 Visual Studio 2010 CLR 中编译

C++ OpenGL, GLFW 绘制一个简单的立方体

c++ - 虚函数和static_cast

c++ - string::size_type 而不是 int