c ++方法的不同输出取决于代码中的位置

时间:2014-05-10 06:52:14

标签: c++

我遇到以下代码问题。基本上,当我将方法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()改变自己状态的可能性。

2 个答案:

答案 0 :(得分:2)

我几乎可以肯定line_cf->size()会返回size_t类型的对象。如果你写,

size_t lsize = line_cf->size();
double r2 = abs(36-lsize);

你将得到相同的大号。

原因是(36-lsize)将评估为size_t类型的值,而lsize39时评估为非常大的值。

当您将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()));   
                       ^^^^^^^^^^^^^^^^