Why is the order of destruction of these functions-local static objects NOT the opposite of their initialization order?

I have two local local objects: One and Two. One constructor and destructor have access through two through GetTwo ():

#include <iostream>

struct One;
struct Two;

const One& GetOne();
const Two& GetTwo();

struct Two {
  const char* value = "It two!";
  Two() { std::cout << "Two construct" << std::endl; }
  ~Two() { std::cout << "Two destruct" << std::endl; }
};

struct One {
  One() {
    std::cout << "One construct" << std::endl;
    const char* twoval = GetTwo().value;
    std::cout << "twoval is: " << twoval << std::endl;
  }
  ~One() {
    std::cout << "One destruct" << std::endl;
    const char* twoval = GetTwo().value;
    std::cout << "twoval is: " << twoval << std::endl;
  }
};

const One& GetOne() {
  static One one;
  return one;
}

const Two& GetTwo() {
  static Two two;
  return two;
}

int main(void) {
  GetOne();
}

I will compile this with g ++ 4.8.4: g ++ -std = C ++ 11 [file_name]

And he outputs:

One construct
Two construct
twoval is: It two!
One destruct
twoval is: It two!
Two destruct

They are built and destroyed in the same order! I read that for static variables of C ++ classes in the same translation unit, the destruction order is always the opposite of the construction order. But I don’t think? Or is this behavior undefined?

, , ++ 11 ++ , . undefined, ? ( , , Two.) , GetOne GetTwo ?

EDIT:

, , , , , One.

++ 11, 6.7, 4:

(8.5) (3.7.1) (3.7.2) . (3.6.2) , , , .... , ; .

, 6.7 3.6.3, :

, .

, : - , "" , , . , , .

? . , , :

#include <iostream>

struct One;
struct Two;

const One& GetOne();
const Two& GetTwo();
void PrintOneValue(const One& one);

struct Two {
  Two() { std::cout << "Two construct" << std::endl; }
  ~Two() {
    std::cout << "start Two destruct" << std::endl;
    PrintOneValue(GetOne());
    std::cout << "end Two destruct" << std::endl;
  }
};

struct One {
  const char* value = "It one!";
  One() {
    std::cout << "start One construct" << std::endl;
    GetTwo();
    std::cout << "end One construct" << std::endl;
  }
  ~One() {
    std::cout << "One destruct" << std::endl;
  }
};

void PrintOneValue(const One& one) {
  std::cout << "One value is: " << one.value << std::endl;
}

const One& GetOne() {
  static One one;
  return one;
}

const Two& GetTwo() {
  static Two two;
  return two;
}

int main(void) {
  GetOne();
}

:

start One construct
Two construct
end One construct
One destruct
start Two destruct
One value is: It one!
end Two destruct

, undefined. , , .

+4
2

++ 14 [basic.start.term]:

, , . [. . -end note]

two one. two - one.

, one - two, , .

+4

ctor :

  One() {
    std::cout << "Start One construct" << std::endl;
    const char* twoval = GetTwo().value;
    std::cout << "twoval is: " << twoval << std::endl;
    std::cout << "Finish One construct" << std::endl;
  }

, Two One. , Two , One , , () .

Start One construct
Two construct
twoval is: It two!
Finish One construct
One destruct
twoval is: It two!
Two destruct
+3

Source: https://habr.com/ru/post/1598137/


All Articles