Jenny Shoars
Jenny Shoars

Reputation: 1102

C++ - If an object is declared in a loop, is its destructor called at the end of the loop?

In C++, an object's destructor is called at the closing "}" for the block it was created in, right? So this means that if I have:

while(some_condition)
{
    SomeClass some_object;
    some_object.someFunction();
    some_variable = some_object.some_member;
}

Then the destructor for the object created in one iteration of the loop will be called at the end of the loop before another object is created, correct?

Thanks.

Upvotes: 16

Views: 7168

Answers (2)

The observable behaviour is that it's called each iteration.

The usual rules about optimisations still apply though. If the compiler is smart and the object simple then compiler can do anything it likes that still produces the correct behaviour, e.g.:

#include <iostream>

struct foo {
  int i;
  foo() : i (-1) {}
  ~foo() { i = 1; }
};

int main() {
  int i = 10;
  while (--i) {
    foo f;
    std::cout << f.i;
  }
}

Compiles to:

.Ltmp5:
        .cfi_def_cfa_register %rbp
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        movl    $_ZSt4cout, %edi
        movl    $-1, %esi
        callq   _ZNSolsEi
        xorl    %eax, %eax
        popq    %rbp
        ret

I.e. unrolled and no sign of that destructor in there (although the observable behaviour is still the same).

Upvotes: 8

Robᵩ
Robᵩ

Reputation: 168626

Yes.

But you could have tested it yourself. This is a language feature that compilers are unlikely to get wrong.

#include <iostream>

struct S {
  S() { std::cout << "S::S()\n"; }
  ~S() { std::cout << "S::~S()\n"; }
};

int main () {
  int i = 10;
  while(i--) {
    S s;
  }
}

Upvotes: 26

Related Questions