C++ 是否定义了函数参数中的内部执行顺序?
假设我们有以下代码片段:C++ 是否定义了函数参数中的内部执行顺序?,c++,c++11,dynamic-memory-allocation,operator-precedence,C++,C++11,Dynamic Memory Allocation,Operator Precedence,假设我们有以下代码片段: void foo(std::unique_ptr<Data> p1, std::unique_ptr<Data> p2){ bar(p1); bar(p2); } int main(){ foo( std::unique_ptr<Data>{new Data}, std::unique_ptr<Data>{new Data}); } void foo(std::unique_ptr p1,std
void foo(std::unique_ptr<Data> p1, std::unique_ptr<Data> p2){
bar(p1);
bar(p2);
}
int main(){
foo( std::unique_ptr<Data>{new Data}, std::unique_ptr<Data>{new Data});
}
void foo(std::unique_ptr p1,std::unique_ptr p2){
巴(p1);
bar(p2);
}
int main(){
foo(std::unique_ptr{new Data},std::unique_ptr{new Data});
}
问题是:在运行此代码时,内存是否总是被释放(无论发生什么情况)
Standard说我们不能依赖语句的顺序作为函数参数,但是内部函数调用/内存分配等呢?在这里重要吗
运行此代码时是否总是释放内存(无论发生什么情况)
在C++17之前:不。一种可能的执行顺序是:
新数据
新数据
唯一\u ptr
构造函数唯一\u ptr
构造函数unique\u ptr
构造函数,因此我们没有任何清理机制来从(1)中释放内存。那会泄漏的。只有在既不扔也不扔的情况下,我们才可以
这就是为什么标准引入了std::make_unique
:
foo( std::make_unique<Data>(), std::make_unique<Data>() );
foo(std::make_unique(),std::make_unique());
没有这个问题-新的现在在内部分组到唯一的\u ptr
构造函数。因此,如果一个成功了,它将已经被包裹在它的RAII防护中
在C++17之后:是。虽然函数参数的求值顺序尚未确定,但有一条新规则规定这种求值不能交错。也就是说,给定f(g(a),h(b))
,潜在的评估顺序是:[f,g,a,h,b]
和[f,h,b,g,a]
。在g
或h
之前,不再可能同时评估a
和b
,这是原始代码的潜在问题 有可以抛出的构造函数不是很糟糕吗?@user3853544operator new
canthrow@user3853544-不,抛出构造函数一点也不坏。抛出实际上是从一个ctor报告错误所能做的最好的事情,所以如果您的ctor失败,它应该抛出。(通常不鼓励从析构函数中抛出。)它是;在17, B/<代码>、<代码> C<代码>和 D<代码>是不确定的排序,不交错。@ USER3553544异常被添加到C++中,以便能够报告来自构造函数的错误(因为它们没有返回值,可以用来返回错误)。