При запуске java
с опцией -cp
, как описано в Windows PowerShell, вы можете получить ошибку, которая выглядит примерно так:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
Чтобы PowerShell принял команду, аргументы опции -cp
должны содержаться в кавычках, как в:
java -cp 'someDependency.jar;.' ClassName
Формирование команды таким образом должно позволить Java обрабатывать аргументы classpath правильно.
По статическим и глобальным объектам я предполагаю, что вы имеете в виду объекты со статическим временем жизни, определенные в области пространства имен. Когда такие объекты определены с локальной областью, правила немного отличаются.
Формально C ++ инициализирует такие переменные в три этапа: 1. Инициализация нуля 2. Статическая инициализация 3. Динамическая инициализация Язык также различает переменные, которые требуют динамической инициализации, и те, которые требуют статической инициализации: все статические объекты (объекты со статическим временем жизни) сначала инициализируются нулем, затем инициализируются объекты со статической инициализацией, а затем происходит динамическая инициализация.
В качестве простого первого приближения динамическая инициализация означает, что должен выполняться некоторый код; обычно статическая инициализация не выполняется. Таким образом:
extern int f();
int g1 = 42; // static initialization
int g2 = f(); // dynamic initialization
Другое приближение было бы в том, что статическая инициализация - это то, что поддерживает C (для переменных со статическим временем жизни), динамическое все остальное.
Как это зависит от компилятора, конечно, при инициализации, но на дисковых системах, где исполняемый файл загружается в память с диска, значения для статической инициализации являются частью образа на диске и загружаются непосредственно системой с диска. В классической системе Unix глобальные переменные будут разделены на три «сегмента»:
Я подозреваю, что многие современные системы все еще используют что-то подобное.
EDIT:
Еще одно замечание: вышеупомянутое относится к C + +03. Для существующих программ C ++ 11, вероятно, ничего не меняет, но он добавляет constexpr
(что означает, что некоторые пользовательские функции могут по-прежнему являться статической инициализацией) и локальные переменные потока, что открывает совершенно новую банку червей .
Предисловие: слово «статический» имеет огромное количество различных значений в C ++. Не путайте.
Все ваши объекты имеют статическую продолжительность хранения . Это потому, что они не являются ни автоматическими, ни динамическими.
В C ++ объекты Static инициализируются в две фазы: статическая инициализация и динамическая инициализация.
int
переменным с постоянным инициализатором, и вам гарантировано, что это действительно инициализируется в статической фазе. Важнейшим моментом является то, что статическая фаза инициализации вообще не выполняется. Данные есть с самого начала. Это означает, что нет никакого «заказа» или любого другого такого динамического свойства, которое относится к статической инициализации. Исходные значения жестко закодированы в двоичном коде программы, если вы это сделаете.
Когда эти четыре переменные инициализированы?
blockquote>Как вы говорите, это происходит до запуска программы, то есть до начала
main
. C не уточняет это; в C ++ это происходит во время фазы статической инициализации перед объектами с более сложными конструкторами или инициализаторами.Где значения для инициализации, такие как 5 и 4, хранятся во время компиляции?
blockquote>Как правило, ненулевые значения сохраняются в сегменте данных в файле программы, а нулевые значения находятся в сегменте bss , который просто резервирует достаточную память для переменные. Когда программа запускается, сегмент данных загружается в память, а сегмент bss устанавливается на ноль. (Конечно, в стандарте языка это не указано, поэтому компилятор мог бы сделать что-то еще, например, генерировать код для инициализации каждой переменной перед запуском
main
).
Парафразировано по стандарту:
Все переменные, не имеющие динамической продолжительности хранения, не имеют продолжительности хранения локального потока и не являются локальными, имеют статическую продолжительность хранения. Другими словами, все глобальные переменные имеют статическую продолжительность хранения.
Статические объекты с динамической инициализацией не обязательно создаются перед первым оператором в основной функции. Реализация определяется, созданы ли эти объекты перед первым оператором в главном или перед первым использованием любой функции или переменной, определенной в той же самой единицы перевода, что и статическая переменная, подлежащая инициализации.
Итак, в вашем коде global_int1 и static_int1 определенно инициализируются перед первым оператором в основном, потому что они статически инициализируются. Однако global_int2 и static_int2 динамически инициализируются, поэтому их инициализация выполняется в соответствии с указанным выше правилом.
Что касается вашего второго момента, я не уверен, что понимаю, что вы имеете в виду. Не могли бы вы уточнить?