Что раньше - загрузка статической библиотеки или инициализация переменной?
От: Molchalnik  
Дата: 27.08.24 12:53
Оценка:
Коллеги!

Такой вопрос.
Статическая переменная при инициализации вызывает функцию из статической библиотеки. пусть то будет хоть переменная в функции (например, синглтон) или глобальная переменная, или статический член класса.
Гарантирует ли стандарт C++, что статическая библиотека загрузится раньше, чем начнётся инициализация статической переменной в главном модуле?

На практике я сталивался с тем, что либа может жагружатся позже. Но было давно, поэтому это не точно — мог забыть и перепутать от времени.
К тому же, это может быть особенностью компилятора, а не требованием стандарта.
Re: Что раньше - загрузка статической библиотеки или инициализация переменной?
От: σ  
Дата: 27.08.24 13:17
Оценка: +5
Чё ещё за «загрузка» у статической библиотеки? Статическая библиотека это разве не архив с объектниками, которые линкуются в исполняемый файл так же, как любые другие объектные файлы?
Re[2]: Что раньше - загрузка статической библиотеки или инициализация переменной
От: Molchalnik  
Дата: 27.08.24 13:25
Оценка:
Здравствуйте, σ, Вы писали:

σ>Чё ещё за «загрузка» у статической библиотеки? Статическая библиотека это разве не архив с объектниками, которые линкуются в исполняемый файл так же, как любые другие объектные файлы?


Хорошо, уточню.

1) есть ли гарантия, что глобальные/статические переменные статической библиотеки инициализируются раньше, чем будет вызвана вышеупомянутая функция?

2) Гарантируется ли стандартом c++ или каким-то документом, что прилинкованная статически библиотека будет инициализироваться точно так же, как и объектник с аналогичным кодом?

или, может быть, для неё будут какие-то свои оптимизации?

например, известная тема, что если упоминаний статической библиотеки нет, то линковщик может просто выкинуть важный инициализирующий код
поэтому иногда добавляют липовый вызов или липовую ссылку на что-то из статической библиотеки

Это точно все отличия?

А если отличий нет, то это особенности линкера или закреплено стандартом?
Re: Что раньше - загрузка статической библиотеки или инициал
От: Chorkov Россия  
Дата: 27.08.24 13:30
Оценка:
Здравствуйте, Molchalnik, Вы писали:

M>Коллеги!


M>Такой вопрос.

M>Статическая переменная при инициализации вызывает функцию из статической библиотеки. пусть то будет хоть переменная в функции (например, синглтон) или глобальная переменная, или статический член класса.
M>Гарантирует ли стандарт C++, что статическая библиотека загрузится раньше, чем начнётся инициализация статической переменной в главном модуле?

M>На практике я сталивался с тем, что либа может жагружатся позже. Но было давно, поэтому это не точно — мог забыть и перепутать от времени.

M>К тому же, это может быть особенностью компилятора, а не требованием стандарта.

С точки зрения стандарта, статическая либа — это набор единиц трансляции, равноправных (по порядку выполнения инициализации) с исходниками текущей программы.
Т.е. сперва инициализируются constant initialization (во всех единицах трансляции, включая либы), и потом конструкторы глобальных пременных и инициализация переменных не-константами (т.е. там, где надо исполнять код для вычисления значений).

В принципе, можно написать написать либу так, что вызов функции на этапе инициализации статических переменных вызовет UB, но это ИМХО саботаж.

С другой стороны, многие либы требуют, чтобы до использования была вызвана специальная функция для настройки работы либы (выбор аллокатора памяти, уровня логгирования, использования палатализации, и т.д.). Для таких либ, вызов их функций на этапе инициализации, тоже (ИМХО) саботаж.
Отредактировано 27.08.2024 13:32 Chorkov . Предыдущая версия .
Re: Что раньше - загрузка статической библиотеки или инициализация переменной?
От: Кодт Россия  
Дата: 03.09.24 13:53
Оценка: +1
Здравствуйте, Molchalnik, Вы писали:

M>На практике я сталивался с тем, что либа может жагружатся позже. Но было давно, поэтому это не точно — мог забыть и перепутать от времени.

M>К тому же, это может быть особенностью компилятора, а не требованием стандарта.

Порядок динамической инициализации статических переменных, а также функций, помеченных как __attribute__((__constructor__)) — определён только в пределах одной единицы трансляции.

Если между несколькими единицами трансляции (в том числе между статическими библиотеками) есть какая-то логическая связь, то выходом будет использовать синглетоны Майерса.

Вот такой код содержит неопределённое поведение из-за неспецифицированного порядка выполнения init_x и init_y
// xxx.cpp

auto g_x = init_x();

// yyy.cpp

auto g_y = init_y(g_x);


А вот такой — уже не содержит
// xxx.cpp

// синглетом Майерса - инициализирует переменную только при первом обращении
const auto& get_g_x() {
  static auto x = init_x();
  return x;
};

// yyy.cpp

auto g_y = init_y(get_g_x());


Хотя, конечно, кольцевые зависимости вида
const auto& get_g_x() { static auto x = init_x(get_g_y()); return x; }
const auto& get_g_y() { static auto y = init_y(get_g_x()); return y; }

по-прежнему приведут к краху.

Синглетоны Майерса тоже, конечно, содержат подводные грабли, но в первом приближении сгодятся.
Перекуём баги на фичи!
Re[3]: Что раньше - загрузка статической библиотеки или инициализация переменной
От: Stanislav V. Zudin Россия  
Дата: 03.09.24 15:20
Оценка: +1
Здравствуйте, Molchalnik, Вы писали:

M>1) есть ли гарантия, что глобальные/статические переменные статической библиотеки инициализируются раньше, чем будет вызвана вышеупомянутая функция?


M>2) Гарантируется ли стандартом c++ или каким-то документом, что прилинкованная статически библиотека будет инициализироваться точно так же, как и объектник с аналогичным кодом?


Прежде всего уточни, о каких статически-линкованных либах идёт речь?

О .lib/.a или о .dll/.so?

Первые линкуются внутрь бинаря, загрузка вторых определяется операционкой.
Гарантируется, что dll будет загружена до того, как будет вызван код внутри либы. Даже с delay-loaded.
_____________________
С уважением,
Stanislav V. Zudin
Re: Что раньше - загрузка статической библиотеки или инициализация переменной?
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.09.24 15:24
Оценка: +1
Здравствуйте, Molchalnik, Вы писали:

M>Гарантирует ли стандарт C++, что статическая библиотека загрузится раньше, чем начнётся инициализация статической переменной в главном модуле?


Стандарт C++ ничего не знает ни о библиотеках, ни о их загрузке.

Но статическая библиотека — это часть самой программы. Как она может загрузиться позже, чем в программе что-то произойдет?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.