Stati c проблема порядка инициализации строки - PullRequest
0 голосов
/ 21 марта 2020

У меня есть extern const объявление строки в заголовочном файле, и его определение в исходном файле:

// a.h
extern const std::string base;

// a.cpp
const std::string base = "base";

Затем у меня есть другая строка extern const в другом заголовочном файле и определение этой строки использует определение первой строки:

// b.h
extern const std::string usage;

// b.cpp
const std::string usage = base + " str";

При запуске приложения я получаю эту ошибку:

Сбой процедуры инициализации библиотеки DLL (DLL) c.

Я подключил отладчик к приложению, получил следующее исключение:

Исключение: нарушение прав чтения. это был nullptr.

Это было брошено в base в b.cpp. Итак, я понял, что это вопрос порядка инициализации stati c. Но в моем make-файле я перечисляю a.obj ДО b.obj, поэтому я не понимаю, почему это происходит.

Обратите внимание, что я получаю эту ошибку только на Windows. Linux в порядке.

Одним из способов является определение base в заголовочном файле:

// a.h
const std::string base = "base";

// a.cpp

Это единственное решение? Или есть лучший способ?

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Вы можете управлять порядком инициализации с помощью #pragma init_seg

указателей на c ++ по умолчанию инициализируется в секции .CRT$XCU (между __xc_a с *) 1010 * и __xc_z от .CRT$XCZ)

, поэтому решение может быть следующим

// a.cpp
#pragma warning(disable : 4075)
#pragma init_seg(".CRT$XCU1")

const std::string base = "base";

и

// b.cpp
#pragma warning(disable : 4075)
#pragma init_seg(".CRT$XCU2")

const std::string usage = base + " str";

, поэтому введите base в ".CRT$XCU1" и usage до ".CRT$XCU2" это гарантия того, что base будет инициализирован до usage

0 голосов
/ 22 марта 2020

Не уверен, почему в заголовке упоминается инициализация строк stati c, и, вероятно, это поведение зависит от используемого компилятора, но в vs2017 вы должны включить заголовок ah в файл b. cpp. Это сработало для меня. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...