статическая переменная во встроенной функции

Меня интересует, что именно происходит «под капотом», когда следующая встроенная функция вызывается в нескольких единицах перевода.

namespace some_name
{
    inline const float& get_float()
    {
        static const float a = 5.0f;
        return a;
    }
}

Мое намерение состояло в том, чтобы создать внешне связанную переменную 'a', которую можно было бы использовать во всем коде (если включен заголовок с пространством имен), но также я хотел предотвратить любое изменение этой переменной. Судя по тестированию, мне это удалось, но мне интересно, что именно происходит, когда я вызываю эту функцию в первый раз, а затем несколько раз в следующий раз.

Дополнительный вопрос: загрязняю ли я глобальное пространство имен объявлением / определением статической переменной?


person FrantišekV    schedule 07.04.2017    source источник
comment
В качестве альтернативы созданию функции, возвращающей статическое значение с плавающей запятой, почему бы просто не сделать ее переменной-членом класса или даже пространства имен; это все еще const ...   -  person UKMonkey    schedule 07.04.2017
comment
UKMonkey Я не был уверен, если я сделаю это так, то каждый раз, когда я использую переменную в другой единице перевода, я получу копию типа const float.   -  person FrantišekV    schedule 07.04.2017
comment
Вы уверены, что этот путь a имеет внешнюю связь? И зачем вам вообще нужна внешняя константа? Внешняя связь предполагает, что несколько единиц компиляции совместно используют один экземпляр переменной, и при его изменении каждая единица будет читать обновленное значение. Но не ожидается, что константа изменится. Более того, во многих случаях компилятор будет вставлять постоянное значение непосредственно в инструкцию, так что оно даже не появится в памяти.   -  person Eduard Malakhov    schedule 07.04.2017
comment
Если вам интересно узнать, здесь нет никакой тайны. Большинство компиляторов могут дать вам представление на уровне сборки о том, какой именно код они для этого сгенерировали.   -  person tadman    schedule 07.04.2017


Ответы (1)


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

Инициализация статическая (не зависит от чего-либо во время выполнения), поэтому она, вероятно, выполняется в начале программы. Все вызовы просто возвращают ссылку на статический объект. И эти вызовы, вероятно, расширяются встроенными, поэтому просто используйте статический объект напрямую.

Более простой вариант - использовать глобальную переменную в пространстве имен.

Дополнительный вопрос: загрязняю ли я глобальное пространство имен объявлением / определением статической переменной?

Нет. Статическая переменная является локальной, поэтому не загрязняет пространство имен. Сама функция действительно «загрязняет» пространство имен, в котором она объявлена.

person eerorika    schedule 07.04.2017
comment
Переменная static в пространстве имен будет делать наоборот, то есть определять одну такую ​​переменную для каждого TU, который включает заголовок. - person Quentin; 07.04.2017
comment
@Quentin да, я имел в виду глобальную переменную (т.е. нелокальную переменную со статическим хранилищем). Однако для констант это не имеет значения, поскольку дубликаты из разных единиц компиляции все равно сжимаются, не так ли? - person eerorika; 07.04.2017
comment
@Quentin Это именно то, что мне интересно. Вот почему я не определил переменную в пространстве имен. Я хочу использовать один конкретный статический объект непосредственно во всех TU, которые включают этот заголовок. - person FrantišekV; 07.04.2017
comment
@ user2079303 не обязательно. Речь идет об использовании ODR, и правила довольно сложные, но в двух словах разница видна, когда вы берете адрес константы. С одним определением (например, локальным static или extern глобальным) адрес будет одинаковым для всех TU, а с static глобальными - нет. - person Quentin; 07.04.2017
comment
@ user3271640, затем используйте extern. - person eerorika; 07.04.2017
comment
Я действительно протестировал это, и если я определил статическую переменную только в пространстве имен, а затем я вызываю переменную из другого TU, я получаю только ее (const float) копию с другим адресом. Я не этого хотел. - person FrantišekV; 07.04.2017
comment
@ user3271640, поэтому вы используете extern, а не static. - person eerorika; 07.04.2017
comment
@ user2079303 Да, extern должен это делать, но не будет ли он загрязнять глобальное пространство имен, когда я вызываю переменную? - person FrantišekV; 07.04.2017
comment
@ user3271640 вы не загрязняете глобальное пространство имен, если помещаете переменную в пространство имен some_name больше, чем вы загрязняете пространство имен функцией. - person eerorika; 07.04.2017
comment
Спасибо за ответы, теперь мне все более понятно. - person FrantišekV; 07.04.2017