2015-08-21 31 views
4

我使用clang分析器來檢查我的C++代碼是否存在錯誤和錯誤。我有以下結構:C++如何處理try catch塊中的賦值?

#include <cstdlib> 
#include <iostream> 

double 
somethingThatMayThrow() throw (std::exception) 
{ 
    if(rand() % 2) { 
     throw std::exception(); 
    } 
    return 5.0; 
} 

int 
main() 
{ 
    double value = 2.0; 
    try { 
     value = somethingThatMayThrow(); 
    } catch(const std::exception&) { 
     std::cout << "oops" << std::endl; 
    } 
    double someOtherValue = value + 1.0; 

    std::cout << someOtherValue << std::endl; 

    return 0; 
} 

分析儀現在抱怨變量value的初始值是從來沒有讀過。然而,當且僅當在try塊中存在異常時,顯然該值用於最後一行。這種理解是否正確,並且我正在分析器中查找錯誤?或者我在這裏錯過了什麼?

該標準如何定義此行爲?如果右側拋出,分配的左側會發生什麼?

的屏幕截圖示出了如下的實際代碼,所述分析器抱怨,其具有相同的結構,我的例子以上:

clang analyzer detects a dead store in a try catch block

+2

我認爲這個消息意味着在'double value = someValue;'中,在將它重新分配給'somethingThatMayThrow()'之前,你永遠不會讀取'value'的值。 – Borgleader

+1

「該值用於最後一行」,否,不在您提供的代碼和圖片中。給出一個**最小但完整的例子。作爲文本。 –

+2

@ Cheersandhth.-Alf他做到了。 – Shoe

回答

4

分析器是錯誤的。你是對的。

分析器可能是正確的,如果在try塊中的代碼可以從不拋出std::exception S或從它衍生的類型的對象(例如,用noexcept,或與其它類型的唯一對象被拋出)。

無論採用哪種方式,您的解釋都是正確的:如果對要拋出的值進行評估,則分配永遠不會發生。因此,原始價值將保持不變。

+0

「如果try塊內的代碼永遠不會拋出「我認爲函數名用純英語說:」somethingThatMayThrow()「 – Slava

+0

@Slava:'Base :: asValue'並不是用簡單的英語來表達,而是實際重現問題的代碼。 –

+0

如果無法解析傳遞給它的字符串,我可以保證'Base :: asValue'將被拋出。所以不用擔心,這不是一個「noexcept」功能。 – Arne

0

編譯器發現您在value的初始化中分配了someValue,但是在try塊的內部,您正在重新分配它。

分析儀正確的情況下,沒有例外拋出,但不是在相反的情況下,其中value仍然是原來的someValue相同。

+1

「分析儀是正確的」這意味着分析儀是錯的 – Slava

+0

@Slava:也許,也許不是。 –