Когда вызывается деструктор объекта constinit?

Обычно говорят, что деструкторы статических объектов вызываются в обратном порядке по отношению к конструкторам. Насколько я понимаю, объекты constinit инициализируются во время компиляции, поэтому их деструкторы должны вызываться после деструкторов обычных статических объектов.

Программа

struct A
{
  constexpr A(const char* t): t_(t) {}
  ~A() {std::cout << "~A(" << t_ << ")\n";} 
  const char* t_;
};  

static A a1("static");  

int main () {
   static constinit A a2("constinit");  
   return 0;
} 

(используя GCC 10), однако, дает вывод

~A(constinit)
~A(static)

т. е. объект constinit уничтожается раньше, чем обычный статический объект (хотя он был создан ранее). Правило обратного порядка больше не действует для объектов constinit?


person Helmut Zeisel    schedule 16.07.2020    source источник
comment
Мне пришлось пересмотреть стандарт, это не ошибка компилятора, константные инициализированные объекты уничтожаются, как если бы они были инициализированы динамически, это указано в стандарте. Нарушение правила обратного порядка соответствует стандарту.   -  person Oliv    schedule 16.07.2020


Ответы (1)


И a1, и a2 инициализированы константами. Спецификатор constinit только утверждает, что определяемая переменная является инициализированной константой. Итак, здесь a1 инициализируется до a2, поэтому a2 уничтожается до a1, как и ожидалось.

Правило обратного порядка больше не действует для constinit объектов? Правило обратного порядка не действует между постоянно инициализируемым объектом и динамически инициализируемым объектом: даже если построение константного инициализированного объекта происходит до построения динамически инициализируемого объекта, уничтожение константно-инициализируемого объекта происходит так, как если бы они были динамически инициализированы: [basic.start.term]/3

Если объект инициализируется статически, он уничтожается в том же порядке, как если бы объект был инициализирован динамически.

person Oliv    schedule 16.07.2020