Lin*_*gxi 27 c++ language-lawyer make-shared exception-safety c++17
在cppref中,以下内容一直持续到C++ 17:
f(std::shared_ptr<int>(new int(42)), g())如果g在之后调用new int(42)并抛出异常,则可能导致内存泄漏的代码,同时f(std::make_shared<int>(42), g())是安全的,因为两个函数调用永远不会交错.
我想知道在C++ 17中引入了哪些更改使其不再适用.
lis*_*rus 20
所述P0145R3纸(其已被接受为C++ 17)细化几个C的评价++结构,包括顺序
后缀表达式从左到右进行计算.这包括函数调用和成员选择表达式
具体而言,本文将以下文本添加到标准的5.2.2/4段:
后缀表达式在表达式列表中的每个表达式和任何默认参数之前进行排序.与参数初始化相关联的每个值计算和副作用以及初始化本身在每个值计算和与任何后续参数的初始化相关联的副作用之前被排序.
xsk*_*xzr 17
函数参数的评估顺序由P0400R0更改.
在更改之前,函数参数的评估相对于彼此没有排序.这意味着g()可以将评估插入到评估中std::shared_ptr<int>(new int(42)),这会导致您引用的上下文中描述的情况.
在更改之后,函数参数的评估是不确定地排序的,没有交错,这意味着所有副作用都std::shared_ptr<int>(new int(42))发生在之前或之后g().现在考虑g()可能抛出的情况.
如果所有副作用std::shared_ptr<int>(new int(42))发生在那之前g(),分配的内存将由析构函数解除分配std::shared_ptr<int>.
如果所有的副作用std::shared_ptr<int>(new int(42))后,那些发生g(),甚至有没有内存分配.
在任何一种情况下,无论如何都没有内存泄漏.