В книге "Программирование: принципы и практика использования С++" приводится следующий пример:
// file f1.cpp
int x1 = 1;
int y1 = x1+2; // y1 becomes 3
// file f2.cpp
extern int y1;
int y2 = y1+2; //UB, y2 becomes 2 or 5
То есть неизвестно, в каком порядке будут инициализированы глобальные переменные. Стоит ли ожидать аналогичного поведения при использовании глобальных констант?:
// file f1.cpp
int x1 = 1;
const int y1 = x1+2; // y1 becomes 3
// file f2.cpp
extern const int y1;
int y2 = y1+2; //UB???
И почему UB возникает вообще? Ведь переменная/константа во втором файле явно объявлена, но не инициализирована, а значит чтобы "узнать" её значение нужно обратиться к определению, а в этом случае y1 явно = 3.
Ведь когда программа вызывает функцию, которая объявлена в первом файле, но определена во втором, она ведь не предполагает, что тело функции пусто (равно нулю), как это происходит в случае с внешними глобальными переменными.
Ответ
Во-первых, вы должны в файле f1.cpp указать, что константа имеет внешнее связывание
extern const int y1 = x1+2; // y1 becomes 3
иначе она будет не видна в файле f2.cpp, так как константы в C++ имеют внутреннее связывание.
Что касается вашего вопроса, то это не имеет значения, является ли переменная константой или нет. Проблема связана с тем, что не определен порядок инициализации статической памяти у модулей.
Что касается функций, то редактор связей просто проставляет адреса для внешних символов. К самим же функциям обращение идет во время выполнения. Поэтому, например, статические переменные функции инициализируются при вызове функции.
Комментариев нет:
Отправить комментарий