2012-12-09 81 views
0

嘿,我只是想知道這些警告中的任何一個會導致.exe在啓動時崩潰。 下面是警告:警告導致.exe中的錯誤?

Warning 1 warning C4244: '=' : conversion from 'double' to 'int', possible loss of data c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\stats.cpp 54 1 MaroonedCA2 
Warning 2 warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\player.cpp 75 1 MaroonedCA2 
Warning 3 warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\player.cpp 92 1 MaroonedCA2 
Warning 4 warning C4018: '<' : signed/unsigned mismatch c:\users\conor\documents\college\dkit - year 2 - repeat\dkit - year 2 - semester 1 - repeat\games programming\maroonedca2\maroonedca2\inventory.cpp 63 1 MaroonedCA2 

1個

int stats[SIZE]; 
    stats[0] = Status.health; 
    stats[1] = Status.strength; 
    stats[2] = Status.hitpoints; 
    stats[3] = Status.armour; 
    stats[4] = Status.luck; 

運氣是一張雙人牀和尚未鑄造。

int Player :: hitPoints() 
    { 
     srand(time(0)); // seed random number generator based on current time 
     int randomNumber= rand(); // generate random number 
     int hitPoints = (randomNumber% 15) + 1; // get a number between 1 and 20 
     return hitPoints; 
    } 

int Player :: fatigue() 
{ 
    srand(time(0)); // seed random number generator based on current time 
    int randomNumber= rand(); // generate random number 
    int fatigue = (randomNumber% 5) + 1; // get a number between 1 and 5 
    return fatigue; 
} 

for (int i= 0; i< inventory.size(); ++i) 
     cout<< inventory[i] << endl; 
    } 
    cout << "\n-----------------------------------------\n"; 
+1

不是我能看到的。但是你應該知道這些警告是關於什麼的,它們很容易修復,並且最好不要養成編寫代碼的習慣。 – PeterJ

+1

好吧,警告對生成的代碼沒有影響,所以沒有。但是,警告可能表明您的代碼中存在可能導致崩潰的錯誤。 (或者你可能有這樣一個錯誤,並沒有警告。)上述警告比直接導致崩潰的東西更多地暗示數據丟失,但是可能存在環路控制或數組索引導致崩潰的問題。 (很好的做法是檢查每個警告,理解它發佈的原因,如果它是一個「非問題」,則插入一個明確的演員或其他任何東西來使其靜音,並表明您理解問題。) –

回答

1

在隔離,沒有這些警告可能導致崩潰。但是,它們可能會導致錯誤地調用其他函數,而這些函數對意外值的響應不好。

您應該爲崩潰獲取堆棧跟蹤以瞭解其發生的原因。調試是一個單獨的主題,所有在一起,你可以通過谷歌獲得大量信息:)

2

這些我可以看到的唯一一個有任何誘導崩潰的實際可能性將是最後一個。如果inventory.size() > INT_MAX,那麼在一個典型的實現中,你將最終從一個負指數讀取。

假設你的程序實際上在啓動時崩潰了,但是如果這是問題的根源,我會感到很驚訝。這比可能的問題來源更理論上的可能性。首先,在啓動時,我猜想inventory.size()可能是0,所以不會發生溢出。其次,我想你只會顯示庫存來響應一個命令,而不是在啓動過程中 - 所以這段代碼在啓動時可能不會執行。

其他人有問題,但不是那些可能導致崩潰的問題。

剛剛例如,你的例子#2,#3使用srand錯誤 - 最正常的程序,幾乎可以肯定包括這一個,應該叫srand正是一次在程序啓動時,永不再叫它。這將導致你的「隨機」數字比他們應該更容易預測,但不會崩潰。

1

你的程序會崩潰嗎?

那麼通常,除非例如,你錯過了一些特殊情況下,在你的程序像雙轉換爲int,但如果這個中斷變爲0,你除以0不檢查這些警告並沒有引起太多的問題。

讓我們通過所有的警告:

Warning 1 warning C4244: '=' : conversion from 'double' to 'int', possible loss of data 

這應該是顯而易見的INT無法存儲的雙所有的值,但並沒有什麼錯,只要你記住,它可能將其轉換已經成爲一個可能導致問題的值(比如轉換爲0),但這取決於你對int的操作。嘗試int toint = static_cast<int>(yourdouble);不應該發出警告。

Warning 2 warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data 

time_t通常有8個字節,uint只有4所以顯然它不能存儲所有的信息。數據丟失可能會導致混淆,當你期望一個值,但你得到一個不同的。

Warning 4 warning C4018: '<' : signed/unsigned mismatch 

再次沒有問題。它只是通知您,一方可能是負值,並在另一種是不可能的,或者一側的最大值比另一側的最大更高。非常常見的警告,通常是因爲程序員懶惰的時候需要將整數定義爲無符號時才發生。

編輯: 我假設你使用VC。下面是關於如何忽略警告當且僅當你確信你不能擺脫他們,他們是完全安全的忽略一個例子(我強烈建議使用一次參數):

http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

1

每警告表明某事不太正確。這可能會影響其他代碼。


In&hellip;

int stats[SIZE]; 
stats[0] = Status.health; 
stats[1] = Status.strength; 
stats[2] = Status.hitpoints; 
stats[3] = Status.armour; 
stats[4] = Status.luck; 

隨着double類型的Status.luck,你要麼丟失信息,或使用過於籠統類型。信息丟失可能會在稍後導致崩潰。過於普遍的類型可能會導致其他地方的錯誤。

的修補程序取決於其中這兩個可能性,它是。


int Player :: hitPoints() 
{ 
    srand(time(0)); // seed random number generator based on current time 
    int randomNumber= rand(); // generate random number 
    int hitPoints = (randomNumber% 15) + 1; // get a number between 1 and 20 
    return hitPoints; 
} 

你依靠從time(0)的參數類型的srand類型的隱式轉換。

time是熵的一個遊戲源可能OK(但是未針對重複調用一個骰子滾動計劃)。但是請在這裏使用static_cast。到記錄形式參數類型。


int Player :: fatigue() 
{ 
    srand(time(0)); // seed random number generator based on current time 
    int randomNumber= rand(); // generate random number 
    int fatigue = (randomNumber% 5) + 1; // get a number between 1 and 5 
    return fatigue; 
} 

重新初始化隨機數發生器。這很可能是一個錯誤。我無法想象每次玩家疲勞時都需要重複相同的行爲。


for (int i= 0; i< inventory.size(); ++i) 
    cout<< inventory[i] << endl; 
    } 
cout << "\n-----------------------------------------\n"; 

你有一些缺失的支柱或支架,和/或凹陷的問題。不幸的是它編譯。但修復它。

符號/無符號不匹配即將簽署i的無符號size_tinventory.size()的比較。在某些情況下,這可能會導致令人討厭的錯誤。例如,表達

string("hello").size() < -3 

永遠是true,由於隱促進-3爲無符號類型,與纏繞。這是非常愚蠢的。非常值得注意。

該循環的最佳修復方法是使用size函數,該函數將大小值轉換爲帶符號的符號,例如,

typedef ptrdiff_t Size; 

template< class Item > 
Size size(std::vector<Item> const& v) { return v.size(); } 

然後

for (int i= 0; i < size(inventory); ++i) 
{ 
    cout<< inventory[i] << endl; 
} 

這樣便於集中解決方案,使其適用於所有將來的代碼。

將循環控制變量更改爲無符號類型只是將問題(特別是隱式轉換問題)推送到另一個地方。請注意,一般來說,不會收到有關此類隱式轉換的任何警告。大多數編譯器只會對直接比較發出警告。

爲了更一般size功能,可以將其定義爲

template< class Container > 
Size size(Container const& c) { return end(c) - begin(c); } 

其中beginend距離<utility>頭C++ 11層的功能。