Рассмотрим классическую задачу, часто встречающуюся на олимпиадах и собеседованиях: напишите
Hello, world!, чтобы телом функции main были пустые фигурные скобки: {}
Классическое решение этой задачи судя по всему содержит ошибку:
#include<iostream>
class hello {
public:
hello(){ std::cout << "Hello, world!\n"; }
} put;
int main(){
}
Ankit Asthana и Ayman Shoukry сообщают:
Цитата:
И дальше о том, что поскольку глобалы могут быть использованы в других единицах трансляции, компилятор не может их выкинуть за ненадобностью; эта обязанность возлагается на компоновщик. Ankit Asthana и Ayman Shoukry — это два программиста, принимавшие непосредственное участие в разработке Visual Studio. К тому же первый является автором многочисленных пособий по C++.
В стандарте языка говорится следующее:
Цитата:
3.7.1
If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in 12.8
Если переменная со статическим классом памяти имеет инициализацию или деструктор с побочными эффектами, она не должна исключаться при оптимизации, даже если она выглядит как неиспользуемая, за исключением того, что классовый объект или его копия или результат перемещения может быть исключен, как указано в 12.8.
Конструктор с инструкцией вывода текста, очевидно, имеет побочный эффект. Вопрос в том, когда он будет вызван.
Цитата:
Должна ли динамическая инициализация нелокальной переменной со статическим классом памяти быть произведена перед первым оператором функции main, определяется реализацией. Если инициализация отложена на некоторый момент времени после выполнения первого оператора функции main, она должна произойти перед первым оdr-использованием (3.2) любой функции или переменной, описанной в той же единице трансляции как переменная, подлежащая инициализации.
Нелокальная переменная со статическим классом памяти инициализируемая с побочными эффектами, должна быть инициализирована, даже если она не оdr-используется (3.2, 3.7.1).
Вызов конструктора — это динамическая инициализация переменной классового типа. Вроде бы реализация имеет право отложить вызов этой функции до первого использования любой другой функции или переменной. Но у нас тело функции main — пустые скобки. В приведенном коде нет каких-то других функций или переменных. Может ли получиться так, что никакой инициализации в данном случае вообще не произойдёт?