Home > Back-end >  Would a shared_ptr be materialized if I'm only calling a method on its object?
Would a shared_ptr be materialized if I'm only calling a method on its object?

Time:09-22

I have a trivial question on c shared_ptrs. Please consider the following pseudo code,

class Foo{
  int run();
}

class Bar{
  // NOTE: returns a shared_ptr, not a const ref
  shared_ptr<Foo> GetFoo() const;
}

Bar bar{...};
int k = bar.GetFoo()->run();

in this scenario, when we call bar.GetFoo(), would a shared_ptr<Foo> be materialized (i.e. creating an atomic_counter, etc)? Or can the compiler simplify the last statement further?

CodePudding user response:

The rules of the language require a shared_ptr<Foo> to be materialized even if it is immediately discarded. Calling ->run() only affects when the temporary is materialized, not whether.

In practice, the rules about when the temporary is materialized are actually just rules about who has to allocate the memory for the temporary object to reside in. The construction of the temporary object occurs before GetFoo even returns, just like pre-C 17. This is because only GetFoo or one of its callees actually knows how to perform the construction (e.g. which arguments to pass to the shared_ptr constructor).

All that being said, the materialization can be elided only if the compiler can prove that it doesn't change the observable behaviour of the program. Since shared_ptr is fairly complicated (it has a control block with atomic counters as you seem to be aware of) it is unlikely that the compiler can prove this. Indeed, even when the definition of the function that creates the shared_ptr resides in the same translation unit, it appears that the initialization and destruction of the shared_ptr object are simply inlined, not elided.

  • Related