是否可以优化未使用的功能参数?

时间:2020-09-04 08:45:20

标签: c++

我试图确保由shared_ptr包裹的对象是活动的,只要通过将其作为值传递来执行函数即可。但是在函数内部根本不使用该对象,因此我只想将其用于“固定”:

void doSomething(std::shared_ptr<Foo>) {
    // Perform some operations unrelated to the passed shared_ptr.
}

int main() {
    auto myFoo{std::make_shared<Foo>()};
    doSomething(std::move(myFoo)); // Is 'myFoo' kept alive until doSomething returns?
    return 0;
}

我确实在不同的优化级别(GCC)上检查了该行为,看来它可以按预期工作,但是我不知道编译器在某些情况下是否仍可以对其进行优化。

3 个答案:

答案 0 :(得分:6)

您不必担心-保证调用站点上的函数参数的生命周期能够在函数调用后继续存在。 (这就是为什么foo(s.c_str())之类的std::string s可以正常工作的原因。)

不允许编译器违反该规则,就像规则一样灵活。

答案 1 :(得分:1)

这很大程度上取决于doSomethingFoo的主体实际外观。例如,考虑以下示例:

struct X 
{
    ~X() { std::cout << "2"; };
};

void f(std::shared_ptr<X>) { std::cout << "1"; }

int main()
{
    auto p = std::make_shared<X>();
    f(std::move(p));
}

此程序具有与以下相同的可观察效果:

int main()
{
  std::cout << "12";
}

和顺序"12"得到保证。因此,在生成的程序集中,可能没有共享的指针被使用。但是,由于内部涉及动态内存分配和虚拟函数调用,因此大多数编译器可能不会执行这种积极的优化,而优化起来就不那么容易了。

答案 2 :(得分:0)

如果内联函数并且复制没有副作用,则编译器可以优化将对象复制到函数参数中的过程。

复制shared_ptr会增加其引用计数,因此它确实有副作用,因此编译器无法对其进行优化(除非编译器可以向自己证明不修改引用计数对程序没有影响)