Исключение переменной со статической продолжительностью хранения

Я столкнулся со следующим правилом (3.7.1/2 N3797):

Если переменная со статической продолжительностью хранения имеет инициализацию или деструктор с побочными эффектами, она не должна быть удалена, даже если она не используется, за исключением того, что объект класса или его копирование / перемещение могут быть удалены, как указано в 12.8.

Правда ли, что если мы объявим переменную со статической продолжительностью хранения, имеющую конструктор или деструктор с побочным эффектом, то память будет выделяться для этой переменной, даже если она не используется?

В частности, я пытаюсь поэкспериментировать со следующим кодом:

#include <csignal>
#include <iostream>
#include <cstdlib>

using std::cout;

struct data_member
{
    data_member(){ cout << "data_member\n"; }
    ~data_member(){ cout << "~data_member\n"; }
};

struct Y
{
    static data_member m;
    Y(){ cout << "Y\n"; }
    ~Y(){ cout << "~Y\n"; }
};

Y y;


int main()
{
}

IdeOne

Почему объект data_member не создан в примере?

1 ответ

Решение

Ну, так говорит стандарт, так что... да.

Как всегда, есть правило "как будто", позволяющее компилятору делать практически все, если только эффект сети одинаков. Я мог бы предположить, что если класс огромен для данных, но конструктор и деструктор (и кто-либо еще) не имеют доступа к этим данным, компилятор может просто вызвать конструктор и деструктор в правильном порядке, не оставляя места для неиспользуемых данных,


Что касается вашего примера, вы объявляете Y::m, но вы никогда не определяете это. Так что его не существует. Если вы попытаетесь получить к нему доступ, вы получите ошибку компоновщика.

Другие вопросы по тегам