Destruction of objects with static storage duration

前端 未结 2 1184
梦谈多话
梦谈多话 2020-12-29 08:18

Consider the following program.

struct s { ~s(); };
void f()
{
    static s a;
}

struct t { ~t() { f(); } };
int main()
{
    static s b;
    static t c;
}
         


        
2条回答
  •  孤独总比滥情好
    2020-12-29 09:06

    In the following Objects refers to objects of static storage duration.

    Objects in the global namespace are created before main.

    Objects in the same compilation unit are created in order of definition.
    The order is undefined across different compilation units.

    Objects in a namespace are created before any function/variable in that namespace is accessed. This may or may not be before main.

    Objects in a function are created on first use.

    Objects are destroyed in reverse order of creation. Note the order of creation is defined by the completion of their CONSTRUCTOR (not when it was called). Thus one object 'x' that creates another 'y' in its constructor will result in 'y' being constructed first.

    If they were not created then they will not be destroyed.

    Is the behavior of the program defined?

    So yes the order is well defined

    b:   Created
    c:   Created
    c:   Destroyed Start
    a:   Created (during destruction of C)
    c:   Destroyed End
    a:   Destroyed  (a was created after b -> destroyed before b)
    b:   Destroyed
    

    Modify the code to see:

    #include 
    
    struct s
    {
        int mx;
        s(int x): mx(x) {std::cout <<  "S(" << mx << ")\n";}
        ~s()            {std::cout << "~S(" << mx << ")\n";}
    };
    void f()
    {
        static s a(3);
    }
    
    struct t
    {
        int mx;
        t(int x): mx(x) { std::cout << "T(" << mx << ")\n";}
        ~t()
        {                 std::cout << "START ~T(" << mx << ")\n";
                          f();
                          std::cout << "END   ~T(" << mx << ")\n";
        }
    };
    int main()
    {
        static s b(1);
        static t c(2);
    }
    

    Output is:

    $ ./a.exe
    S(1)
    T(2)
    Start ~T(2)
    S(3)
    END   ~T(2)
    ~S(3)
    ~S(1)
    

提交回复
热议问题