Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是否定义了函数参数中的内部执行顺序?_C++_C++11_Dynamic Memory Allocation_Operator Precedence - Fatal编程技术网

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
    构造函数
  • 如果(1)投,我们就可以了。如果(2)抛出,我们实际上还没有运行
    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
    ,这是原始代码的潜在问题

    有可以抛出的构造函数不是很糟糕吗?@user3853544
    operator new
    canthrow@user3853544-不,抛出构造函数一点也不坏。抛出实际上是从一个ctor报告错误所能做的最好的事情,所以如果您的ctor失败,它应该抛出。(通常不鼓励从析构函数中抛出。)它是;在17, B/<代码>、<代码> C<代码>和 D<代码>是不确定的排序,不交错。@ USER3553544异常被添加到C++中,以便能够报告来自构造函数的错误(因为它们没有返回值,可以用来返回错误)。