Линковка констант
Сегодня начнем затрагивать вопрос линковки переменных, линковки в целом и тонкости этого процесса. На эту тему несколько постов, плавно перетекающих друг в друга.
Давайте предположим, что у нас есть некоторый набор констант. Пусть это будут тривиальные физические константы, типа скорости света, числа авагадро и тд. И мы хотим использовать эти константы в разных единицах трансляции. Очевидный вариант - вынести их в какой-нибудь хэдер и подключать его всякий раз при необходимости. Получаем что-то типа такого:
Используем здесь constexpr для появления возможности использования этих констант в compile-time вычислениях.
Почему это вообще работает? Мы ведь здесь подключаем одно и то же определение в разные юниты трансляции. ODR должно нам запретить такое делать.
Дело в том, что все константы имеют по умолчанию внутреннее связывание. То же самое и для constexpr. Внутреннее связывание гарантирует, что в каждом юните трансляции будет использоваться своя копия этих переменных и ни из какого другого юнита нельзя будет получить доступ к ним. То есть определение этих констант везде будет свое. И ODR не будет нарушаться.
Если пометить константы как static, то ничего толком не изменится, потому что они и так неявно статические. То есть с внутренним связыванием.
У такого подхода есть проблемы.
Каждый раз, когда мы включаем заголовочный файл с константами в файл с кодом, каждая из этих переменных копируется в файл с кодом. Поэтому, если constants.hpp включается в 20 различных файлов кода, каждая из этих переменных дублируется 20 раз. Из этого следует следующее:
1️⃣ Изменение одной константы потребует перекомпиляции каждого файла, использующего константы(даже если измененная константа там не используется!), что делает компиляцию долгой для крупных проектов.
2️⃣ Если константы имеют большой размер и не могут быть оптимизированы, это приведёт к нежелательному расходу памяти.
Какое здесь решение? Подождать следующего поста, там будут объяснения)
Solve the problems. Stay cool.
#cppcore #compiler
Сегодня начнем затрагивать вопрос линковки переменных, линковки в целом и тонкости этого процесса. На эту тему несколько постов, плавно перетекающих друг в друга.
Давайте предположим, что у нас есть некоторый набор констант. Пусть это будут тривиальные физические константы, типа скорости света, числа авагадро и тд. И мы хотим использовать эти константы в разных единицах трансляции. Очевидный вариант - вынести их в какой-нибудь хэдер и подключать его всякий раз при необходимости. Получаем что-то типа такого:
// constants.hpp
#pragma once
namespace constants
{
constexpr unsigned light_speed { 299 792 458 };
constexpr double avogadro { 6.0221413e23 };
// ... other related constants
}
Используем здесь constexpr для появления возможности использования этих констант в compile-time вычислениях.
Почему это вообще работает? Мы ведь здесь подключаем одно и то же определение в разные юниты трансляции. ODR должно нам запретить такое делать.
Дело в том, что все константы имеют по умолчанию внутреннее связывание. То же самое и для constexpr. Внутреннее связывание гарантирует, что в каждом юните трансляции будет использоваться своя копия этих переменных и ни из какого другого юнита нельзя будет получить доступ к ним. То есть определение этих констант везде будет свое. И ODR не будет нарушаться.
Если пометить константы как static, то ничего толком не изменится, потому что они и так неявно статические. То есть с внутренним связыванием.
У такого подхода есть проблемы.
Каждый раз, когда мы включаем заголовочный файл с константами в файл с кодом, каждая из этих переменных копируется в файл с кодом. Поэтому, если constants.hpp включается в 20 различных файлов кода, каждая из этих переменных дублируется 20 раз. Из этого следует следующее:
1️⃣ Изменение одной константы потребует перекомпиляции каждого файла, использующего константы(даже если измененная константа там не используется!), что делает компиляцию долгой для крупных проектов.
2️⃣ Если константы имеют большой размер и не могут быть оптимизированы, это приведёт к нежелательному расходу памяти.
Какое здесь решение? Подождать следующего поста, там будут объяснения)
Solve the problems. Stay cool.
#cppcore #compiler