Использование глобальной переменной для инициализации другой глобальной переменной в разных единицах компиляции - PullRequest
0 голосов
/ 05 июня 2018

У меня есть общая библиотека, которая экспортирует функцию, которая возвращает строку из глобальной переменной, например:

test.h:

const std::string &test_get_name();

test.cpp:

static std::string name = "Test";
const std::string &test_get_name() {return name;}

В моей основной программе (которая связывается с общей библиотекой) я определяю глобальную переменную (она все еще называется «глобальной» переменной, если она статическая?), Которая использует эту функцию для инициализации объекта:

main.cpp:

#include "test.h"
#include <iostream>
struct TestStruct
{
    std::string value;
};
static TestStruct v{test_get_name()};

int main(int argc,char *argv[])
{
    std::cout<<v.value<<std::endl;
    return 0;
}

Насколько я понимаю, это должно быть неопределенным поведением, поскольку переменная 'name' не обязательно инициализируется еще при создании объекта структуры, это правильно??Если это так, было бы правильно, если бы я переместил переменную name в "test_get_name"?:

const std::string &test_get_name()
{
    static std::string name = "Test";
    return name;
}

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

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

Если это вас беспокоит, код, сгенерированный этой функцией, не выглядит слишком плохим(и gcc, и clang создают временную строку):

const std::string test_get_another_name()
{
    return "Test 2";
}

И, конечно, static TestStruct v{test_get_another_name()}; безопасен.

Вы найдете и test_get_name, и test_get_another_name вСсылка Godbolt выше, чтобы вы могли сравнить код, сгенерированный двумя функциями.

0 голосов
/ 05 июня 2018

Статическая переменная внутри функции будет инициализирована при первом вызове функции, так что да, она будет работать.

Для вещей, отличных от string, таких как класс с большим количеством побочных эффектов, может быть разница, если функция не вызывается, объект никогда не будет создан вообще.

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