Например, есть искусственный пример: ...
int main() {
/*
некоторый код
*/
...{
static int someVal = 42;
}
}
Когда произойдет создание переменной? Во время запуска программы или когда доберемся до нужной инструкции?
Вопрос не имеет однозначного ответа, ибо ответ на него в общем случае критически зависит от типа объекта. В вашем конкретном примере с типом int
- объект всегда создается строго во время запуска программы.
А в общем случае это зависит от того, что вы называете "созданием".
У объектов в С++ есть "период хранения" (storage duration) и "время жизни" (lifetime).
Период хранения - это период выделения-освобождения "сырой" памяти, занимаемой объектом.
Период хранения любых статических объектов - это всегда безусловно все время выполнения программы.
Время жизни - это период между [нетривиальной] инициализацией и [нетривиальной] деструкцией объекта в этой сырой памяти. Время жизни всегда вложено в период хранения. Время жизни зависит от свойств объекта.
Если инициализация объекта тривиальна (т.е. если это не-класс тип или класс тип, инициализируемый тривиальным конструктором по умолчанию), то конструкции не требуется вообще и начало периода хранения автоматически является началом времени жизни.
Аналогично если деструкция объекта тривиальна (т.е. если это не-класс тип или класс тип с тривиальным деструктором), то время жизни длится до конца периода хранения.
Если статический объект требует нетривиальной конструкции, то она будет выполнена в момент первого прохода процесса выполнения по объявлению объекта (если такой момент вообще наступит).
Также, если объект скалярного типа (такого как типа int
) инициализируется константным выражением, то такая инициализация будет выполнена статически (еще на старте программы). Если же выражение неконстантно, на старте программы такой объект будет инициализирован нулем, а инициализация выражением будет выполнена позже, динамически. В случае объекта, объявленного локально, это произойдет в момент первого прохода процесса выполнения по объявлению объекта (если такой момент вообще наступит).
В вашем случае вы имеет дело с статическим объектом типа int
. Период хранения такого объекта - все время выполнения программы. И так как это не-класс тип, время жизни этого объекта - все время выполнения программы. Также язык гарантирует вам, что инициализация этого объекта делается статически - не во время первого прохода выполнения по объявлению этого объекта, а сразу на старте программы.
Например, вот такой код гарантированно выведет 42
// Продолжительность хранения `i` уже началась
// Время жизни `i` уже началось
// `i` уже проинициализировано значением 42
int main()
{
goto skip;
static int i = 42; // Статическая инициализация
skip:
std::cout << i << std::endl;
}
А вот такой гарантированно выведет 0
// Продолжительность хранения `i` уже началась
// Время жизни `i` уже началось
// `i` уже проинициализировано значением 0
int main()
{
goto skip;
static int i = std::rand(); // Динамическая инициализация
skip:
std::cout << i << std::endl;
}
Если вы замените int
на std::string
, то период хранения такого объекта - все равно все время выполнения программы. А вот время жизни этого объекта начнется тогда, когда выполнение в первый раз пройдет по его объявлению (если такой момент вообще наступит).
Например, вот такой код
// Продолжительность хранения `s` уже началась
// Время жизни `s` еще не началось
// Однако все члены `s` уже проинициализированы нулями
int main()
{
goto skip;
static std::string s = "Hello World!"; // Динамическая инициализация и начало жизни
skip:
std::cout << s << std::endl;
}
увидит объект s
, по которому пока что только успел проехаться каток огульной нулевой инициализации, но конструкции не выполнялось. Время жизни объекта так и не началось. Поведение не определено.
При первом выполнении кода.
Можно убедиться, создавая, например, переменную некоторого класса с конструктором.
struct Test
{
Test(int x) { cout << x << endl; }
};
int main()
{
for(int i = 0; i < 10; ++i)
{
cout << i << endl;
static Test t = 42;
}
}
Получим
0
42
1
2
3
4
5
6
7
8
9
А что такое создание переменной, как не вызов конструктора? :)
Подозреваю, что зависит от дальнейшего кода и/или настроек компилятора. Такой пример
static int someVal = 42;
printf ("0x%X", someVal);
Дает на выходе такой код:
.text:0040101E push 42
.text:00401020 push offset Format ; "0x%X"
.text:00401025 call esi ; __imp__printf
То есть переменной как таковой и нет, компилятор соптимизировал ее в константу. А вот такой код:
printf ("0x%X", someVal);
someVal++;
printf ("0x%X", someVal);
Приводит к созданию глобальной переменной, инициализированной во время компиляции.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Вот уж не знаю то ли вопрос такой глупый, то ли я действительно такой большой оригинал, но найти какую-то информацию по своему вопросу я не смогА...
Можно ли в конструкторе класса проверить некое условие и сразу запустить деструктор, если условие не удовлетворяется? Или же придется бросать...
Нужно разделить очередь на две, в одну значения большие или равные среднему,во вторую меньшие,при этом не создавая новую(задание такое)Как...