2015-08-21 35 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:也许,也许不是。 –