JJacobsson
JJacobsson

Reputation: 153

How does the compiler resolve infinite reference loops?

// edited by Neil Butterworth to conserve vertical space
#include <stdio.h>

struct A;
struct B;

A& GetAInstance();
B& GetBInstance();

struct A {  
    A() {
        printf( "A\n" );
    }
    ~A() {
        printf( "~A\n" );
        B& b = GetBInstance();
    }
};

struct B {
    B() {
        printf( "B\n" );
    }

    ~B() {
        printf( "~B\n" );
        A& a = GetAInstance();
    }
}; 

A& GetAInstance() {
    static A a;
    return a;
}

B& GetBInstance() {
    static B b;
    return b;
}

int main( ) {
    A a;
}

Consider the above scenario. I would expect this to result in an infinite reference loop resulting in the program being unable to exit from static de-initialization, but the program ran just fine with the following printout:

  A
  ~A
  B
  ~B
  A
  ~A

Which was unexpected.

How does a compiler deal with this situation? What algorithms does it use to resolve the infinite recursion? Or have I misunderstood something fundamental? Is this, somewhere in the standard, defined as undefined?

Upvotes: 2

Views: 1348

Answers (2)

James Hopkin
James Hopkin

Reputation: 13973

The compiler effectively stores a bool with each static to remember whether it has been initialised.

This is the order:

Inside main:

  • Construct A
  • Destruct A
    • Construct static B

Clean-up of statics:

  • Destruct static B
    • Construct static A
    • Destruct static A

3.6.3/1 in the Standard specifies it should work this way, even when a static is constructed during clean-up as in this case.

Upvotes: 6

Ricardo Amores
Ricardo Amores

Reputation: 4687

That behaviour is probably caused because you are using static instances. The compiler surely takes care of the status of static variables to avoid performing multiple initialization / deinitializations.

Upvotes: 0

Related Questions