Home > Enterprise >  Taking the address of a returned temporary object
Taking the address of a returned temporary object

Time:04-30

I have a piece of C 20 code that I believe is valid, but our static analyzer thinks it's unsafe.

struct Foo {
  explicit Foo() { activeFoo = this; }
  ~Foo() { activeFoo = nullptr; }

  Foo(const Foo&) = delete;
  Foo(Foo&&) = delete;

  inline static const Foo* activeFoo = nullptr;
};

Foo makeFoo()
{
  // Is there a dangling reference here?
  return Foo();
}

int main()
{
  auto myFoo = makeFoo();
}

My static analyzer thinks makeFoo causes activeFoo to point to a temporary object and will become a dangling pointer. I believe this is wrong; the return Foo(); should get a guaranteed copy elision (as evidenced by the deleted copy & move constructors), so there is only ever one Foo instance constructed, myFoo.

Who is correct?

CodePudding user response:

makeFoo and copy elision (which as you noted is guaranteed in this specific example since C 17) don't even matter.

activeFoo can never be dangling. If it was pointing to an object after its lifetime ended, then the destructor of that object would have reset activeFoo to nullptr, meaning it cannot be pointing to the object, a contradiction. That is assuming the destructor is called for every created object of type Foo. Technically this might not always be the case if you placement-new objects explicitly, although it should.

I would however not generally expect a static analyzer to figure out this logic. Without some details on the static analyzer or what exactly it complains about, it will be hard to say more.

  • Related