Страницы

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

четверг, 23 января 2020 г.

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

#cpp #language_lawyer


В книге "Программирование: принципы и практика использования С++" приводится следующий
пример:

// 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.
Ведь когда программа вызывает функцию, которая объявлена в первом файле, но определена
во втором, она ведь не предполагает, что тело функции пусто (равно нулю), как это происходит
в случае с внешними глобальными переменными.
    


Ответы

Ответ 1



Во-первых, вы должны в файле f1.cpp указать, что константа имеет внешнее связывание extern const int y1 = x1+2; // y1 becomes 3 иначе она будет не видна в файле f2.cpp, так как константы в C++ имеют внутреннее связывание. Что касается вашего вопроса, то это не имеет значения, является ли переменная константой или нет. Проблема связана с тем, что не определен порядок инициализации статической памяти у модулей. Что касается функций, то редактор связей просто проставляет адреса для внешних символов. К самим же функциям обращение идет во время выполнения. Поэтому, например, статические переменные функции инициализируются при вызове функции.

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

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