2014-05-10 19 views
1

我對下面的代碼有問題。基本上,當我將方法size()直接放入表達式中時,我獲得了意想不到的輸出。當我運行該方法並將其輸出分配給一個變量,然後在表達式中使用該變量時,不再有問題。C++方法的不同輸出取決於代碼中的位置

當我與我的調試器中運行該代碼

 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 

行是用戶定義的類。

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()正在改變自己的狀態的可能性。

+5

[MCVE(HTTP://計算器。com/help/mcve)或者它沒有發生。您的代碼中某處可能存在未定義行爲,可能與您展示的內容完全無關。使用valgrind可能會給你一個線索。 – Mat

+4

如果您可以發佈[sscce](http://www.sscce.org/),可能會更好......首先,您對Line的定義應該是'class Line:public std :: list { ...} ......否則世界其他地方將無法從列表中訪問'size()'方法...(除非你有自己的'size()'方法...)在這種情況下,我們需要看看它)。 – jsantander

+2

可以發佈'Line :: size()'的代碼嗎?我的猜測是調用這個方法改變了'Line'對象的內部狀態,因此它爲隨後的調用返回垃圾。 – Rakib

回答

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)中使用該變量時,會得到一個有符號的整數相減結果,該結果以更明智的方式工作。

+0

我認爲這是正確的。當我將'line_cf-> size()'強制轉換爲int時,我得到了正確的結果。謝謝。 – user1505520

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打印。

爲了保證有符號運算時,與36ll更換常數36,或者投line_cf->size()int(這是你的第二個代碼片段會發生什麼):

double r2 = abs(36-static_cast<int>(line_cf->size())); 
         ^^^^^^^^^^^^^^^^  
相關問題