我遇到以下代码问题。基本上,当我将方法size()
直接放在表达式中时,我得到了意想不到的输出。当我运行该方法并将其输出分配给变量,然后在表达式中使用该变量时,我不再有问题。
当我使用调试器
运行此代码时 Line * line_cf = music.getLine("cf");
... some other code ...
{
int lsize = line_cf->size();
double r2 = abs(36-(line_cf->size()));
}
我得到r2的奇怪值
lsize -> 39
r2 -> 1.8446744073709552e+19
如果我改为运行此代码
Line * line_cf = music.getLine("cf");
... some other code ...
{
int lsize = line_cf->size();
double r2 = abs(36-lsize); // <---
}
我得到r2
lsize -> 39
r2 -> 3
Line是用户定义的类。
class Line : std::list<TonalNote> {
public:
std::string id;
MusicStyle style;
};
更新1:
我尝试删除括号内的第一行,所以我现在有以下代码。
Line * line_cf = music.getLine("cf");
... some other code ...
{
double r2 = abs(36-(line_cf->size()));
}
仍为r2
获得相同的奇怪价值。所以我认为这消除了Line::size()
改变自己状态的可能性。
答案 0 :(得分:2)
我几乎可以肯定line_cf->size()
会返回size_t
类型的对象。如果你写,
size_t lsize = line_cf->size();
double r2 = abs(36-lsize);
你将得到相同的大号。
原因是(36-lsize)
将评估为size_t
类型的值,而lsize
为39
时评估为非常大的值。
当您将line_cf->size()
的返回值存储在int
中并在(36-lsize)
中使用该变量时,您将获得一个有符号整数减法结果,该结果以更合理的方式工作。< / p>
答案 1 :(得分:2)
size()
返回一个64位无符号整数,因此减法36 - (line_cf->size())
发生在64位无符号整数类型中,导致算术回绕到2^64
。
例如:
#include <iostream>
#include <cmath>
int main() {
std::cout << static_cast<double>(std::fabs(36 - 39ull));
}
打印1.84467e+19
。
要确保签名算术发生,请将常量36
替换为36ll
,或将line_cf->size()
转换为int
(这是您的第二个代码摘录中发生的情况):< / p>
double r2 = abs(36-static_cast<int>(line_cf->size()));
^^^^^^^^^^^^^^^^