评估顺序,例外

时间:2016-03-22 16:24:56

标签: c++ language-lawyer

如果在赋值的rhs上抛出异常,则在下面的表达式中,即: bad_alloc linesArg 已经减少了吗?:

try{    
  buffer[--linesArg] = new char[rows];
}catch(std::bad_alloc& ba){

}

3 个答案:

答案 0 :(得分:5)

作业不是sequence point。因此,子表达式的评估顺序是未指定的。编译器可以选择任何订单。每次编译时它甚至可能选择不同的顺序。

您应该将--linesArg表达式提取到自己的语句中,以获得明确定义的行为。

答案 1 :(得分:3)

不,操作数的Order of evaluation未指定。

  

几乎所有C ++运算符的操作数的评估顺序(包括函数调用表达式中函数参数的评估顺序以及任何表达式中子表达式的评估顺序)都未指定。编译器可以按任何顺序计算操作数,并且可以在再次计算同一表达式时选择另一个顺序。

     

此规则有几个例外(例如,对于&&,||和,运算符),如下所述。

     

否则,C ++中没有从左到右或从右到左评估的概念。这不应与运算符的从左到右和从右到左的关联性混淆:表达式f1()+ f2()+ f3()被解析为(f1()+ f2())+ f3( )由于operator +的从左到右的关联性,但是对f3的函数调用可以在运行时的第一个,最后一个或f1()或f2()之间进行计算。

buffer[--linesArg] = new char[rows];

被解析为

operator=(operator[](buffer, --linesArg), new char[rows]);

在调用函数之前将评估参数(即buffer--linesArg将在调用operator[]之前进行评估,operator[]()new char[rows]将被评估在operator=之前调用,仅此而已。),但未指定参数的评估顺序。因此,无法保证在--linesArg之前评估new char[rows]

最好使命令清晰明确,以避免未指明的行为和混淆。

--linesArg;
buffer[linesArg] = new char[rows];

答案 2 :(得分:0)

有序列点;所以在分配完成后,(所谓的副作用)减量肯定会发生。在此之前它未指定。