Выполнение функции времени компиляции - Compile time function execution

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

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

Примеры

В Лисп Система макросов является ранним примером использования оценки пользовательских функций во время компиляции на том же языке.

Расширение Metacode для C ++ (Vandevoorde 2003)[1] была ранней экспериментальной системой, позволяющей оценивать функции времени компиляции (CTFE) и вводить код в качестве улучшенного синтаксиса для C ++. метапрограммирование шаблона.

В более ранних версиях C ++, метапрограммирование шаблона часто используется для вычисления значений во время компиляции, например:

шаблон <int N>структура Факториал {  перечислить { ценить = N * Факториал<N - 1>::ценить };};шаблон <>структура Факториал<0> {  перечислить { ценить = 1 };};// Факториал <4> :: value == 24// Факториал <0> :: value == 1пустота Фу() {  int Икс = Факториал<0>::ценить;  // == 1  int у = Факториал<4>::ценить;  // == 24}

Используя оценку функции во время компиляции, код, используемый для вычисления факториала, будет аналогичен тому, который можно было бы написать для оценки во время выполнения, например. с использованием C ++ 11 constexpr.

#включают <cstdio>constexpr int Факториал(int п) { возвращаться п ? (п * Факториал(п - 1)) : 1; }constexpr int f10 = Факториал(10);int главный() {  printf("% d п", f10);  возвращаться 0;}

В C ++ 11, этот метод известен как обобщенные постоянные выражения (constexpr).[2] C ++ 14 ослабляет ограничения on constexpr - разрешение локальных объявлений и использования условных выражений и циклов (общее ограничение, согласно которому все данные, необходимые для выполнения, должны быть доступны во время компиляции, остается).

Вот пример вычисления функции времени компиляции в C ++ 14:

// Итерационный факториал во время компиляции.constexpr int Факториал(int п) {  int результат = 1;  пока (п > 1) {    результат *= п--;  }  возвращаться результат;}int главный() {  constexpr int f4 = Факториал(4);  // f4 == 24}

Вот пример вычисления функции времени компиляции в Язык программирования D:[3]

int факториал(int п) {    если (п == 0)       возвращаться 1;    возвращаться п * факториал(п - 1);}// вычисляется во время компиляцииперечислить у = факториал(0); // == 1перечислить Икс = факториал(4); // == 24

В этом примере указана допустимая функция D, называемая «факториал», которая обычно оценивается во время выполнения. Использование перечислить сообщает компилятору, что инициализатор для переменных должен быть вычислен во время компиляции. Обратите внимание, что аргументы функции также должны быть разрешены во время компиляции.[4]

CTFE можно использовать для простого заполнения структур данных во время компиляции (D версия 2):

int[] genFactorials(int п) {    авто результат = новый int[п];    результат[0] = 1;    для каждого (я; 1 .. п)        результат[я] = результат[я - 1] * я;    возвращаться результат;}перечислить факториалы = genFactorials(13);пустота главный() {}// Факториалы содержат во время компиляции:// [1, 1, 2, 6, 24, 120, 720, 5_040, 40_320, 362_880, 3_628_800,//  39_916_800, 479_001_600]

CTFE можно использовать для генерации строк, которые затем анализируются и компилируются как код D в D.

Рекомендации

  1. ^ Дэвид Вандевурд, Edison Design Group (18 апреля 2003 г.). «Рефлексивное метапрограммирование в C ++» (PDF). Получено 19 июля, 2015.
  2. ^ Габриэль дос Рейс и Бьярн Страуструп (март 2010 г.). "Общие константные выражения для языков системного программирования. SAC-2010. 25-й симпозиум ACM по прикладным вычислениям" (PDF).
  3. ^ Спецификация языка D 2.0: Функции
  4. ^ Спецификация языка D 2.0: Атрибуты

внешняя ссылка