TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.35K subscribers
Post #750 5.27K
​​Как определять константы локальных функций
#новичкам

Когда мы определяем константу в скоупе функции у нас есть несколько вариантов, как это сделать: пометить const, constexpr, const static, constexpr static. Какой вариант выбрать?

Идентификатор constexpr говорит о том, что значение переменной обязательно должно быть известно во время компиляции. Просто const перед локальной переменной такого не требует, это обычная константа времени выполнения. Ну а static в этом контекcте продлевает время жизни переменной до конца работы программы.

Особенности функционала диктуют кейсы применения.

1️⃣ Если константа зависит от входных данных функции, то ее нужно помечать, как const. constexpr здесь по определению не подойдет, не-consteval функции могут выполняться в рантайме, а в consteval функциях входные параметры не считаются за constexpr. static тоже, потому что один раз определив статическую константу, вы ее не сможете поменять.

std::pair<double, double> normalizeVector(double x, double y) {
const double LENGTH = std::sqrt(x * x + y * y); // Зависит от x и y
return {x / LENGTH, y / LENGTH};
}


2️⃣ Если константа не зависит от входных данных функции и она известна во время компиляции, то лучше ее определить, как constexpr static. Тогда такая локальная переменная гарантированно не будет занимать пространство на стеке при каждом вызове функции, ее инициализация точно пройдет в compile-time и об этом будет явно сказано в коде программы.

double metersToMiles(double meters) {
constexpr static double METERS_IN_MILE = 1609.34;
return meters / METERS_IN_MILE;
}


Вообще этот пост в принципе родился из вопроса: "как помечать локальные константы, значения которых известны на этапе компиляции?". В большинстве случаев можно пометить константу просто constexpr, компилятор скорее всего ее оптимизирует и вставит ее значение в места вызовов, но это не гарантируется. Например, если вы по каким-то причинам будете использовать адрес этой локальной константы, то компилятор будет вынужден класть ее на стек на каждом вызове.

Зачем делать ненужные действия? Если значение переменной не меняется от вызова к вызову, то она больше подходит на глобальную константу. А чтобы не засорять глобальный скоуп переменной, которая используется только в этой функции, то можно сделать ее статической локальной переменной и получить тот же результат.

Be expressive. Stay cool
  • ❤ 21
  • 👍 15
  • 🔥 6
  • 😁 4
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →