Страницы

Поиск по вопросам

пятница, 15 марта 2019 г.

Неопределенное поведение при определении/объявлении внешних глобальных констант

В книге "Программирование: принципы и практика использования С++" приводится следующий пример:
// 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++ имеют внутреннее связывание.
Что касается вашего вопроса, то это не имеет значения, является ли переменная константой или нет. Проблема связана с тем, что не определен порядок инициализации статической памяти у модулей.
Что касается функций, то редактор связей просто проставляет адреса для внешних символов. К самим же функциям обращение идет во время выполнения. Поэтому, например, статические переменные функции инициализируются при вызове функции.

Комментариев нет:

Отправить комментарий