اجرای تابع کامپایل زمان

اجرای تابع زمان-کامپایل (یا ارزیابی تابع کامپایل-زمان ، یا عبارات ثابت عمومی ) یک توانایی کامپایلر است برای نمایش تابع در زمان کامپایل که می تواند به طور عادی یک تابع را به کد ماشین کامپایل کرده و آن را به هنگام اجرا نمایش دهد. این امر در صورتی امکان پذیر است که آرگومانهای مربوط به تابع در زمان کامپایل شناخته شده باشند و تابع هیچ ارجاع یا جستجویی برای حالت های جهانی نسازد ( یک تابع ساده باشد).

اگر مقدار تنها چند آرگومان شناخته شده باشد کامپایلر ممکن است همجنان بتواند چند مرحله از تابع کامپایل-زمان را انجام و نشان دهد (ارزیابی جزئی)، احتمالاً کد بهینه سازی شده بیشتری نسبت به اینکه هیچ استدلالی شناخته نشده بود ، تولید می کند.

مثال ها 
سیستم ماکرو Lisp یک مثال اولیه استفاده از تابع کامپایل-زمان برای توابع تعریف شده توسط کاربر در یک زبان است.

توسعه Metacode به (Vandevoorde 2003) یک سیستم آزمایشی اولیه بود تا به تابع کامپایل-زمان اجازه اجرا دهد (CTFE) و تزریق کد به عنوان یک پیشرفت نحوی یافته برای قالب برنامه نویسی C++ بود.

در نسخه های اولیه C ++ ، از قالب برنامه نویسی Metacode برای محاسببه مقادیر زمان کامپایل استفاده می شد مثل: template <int N>
struct Factorial {
 enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> {
 enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void Foo() {
 int x = Factorial<0>::value; // == 1
 int y = Factorial<4>::value; // == 24
}با استفاده از اجرای تابع کامپایل-زمان ، کدی که برای محاسبه فاکتوریل استفاده می شود مشابه آنچه برای ارزیابی زمان اجرا نوشته می شود، به عنوان مثال استفاده از ترکیب C ++ 11.#include <cstdio>

constexpr int Factorial(int n) { return n ? (n * Factorial(n - 1)) : 1; }

constexpr int f10 = Factorial(10);

int main() {
 printf("%d\n", f10);
 return 0;
}در C ++ 11 ، این تکنیک به عنوان تعمیم عبارت های ثابت شناخته شده است. C++14 برای راحت کردن قیدها روی عبارت های ثابت - اعلان محلی آزاد و استفاده از حلقه ها و قیدهای شرطی (انحصار عمومی) است. 

در اینجا مثالی از ارزیابی تابع زمان کامپایل در C ++ 14 آورده شده است:// Iterative factorial at compile time.
constexpr int Factorial(int n) {
 int result = 1;
 while (n> 1) {
  result *= n--;
 }
 return result;
}

int main() {
 constexpr int f4 = Factorial(4); // f4 == 24
}در اینجا مثالی از ارزیابی تابع کامپایل-زمان در زبان برنامه نویسی D آورده شده است : int factorial(int n) {
  if (n == 0)
    return 1;
  return n * factorial(n - 1);
}

// computed at compile time
enum y = factorial(0); // == 1
enum x = factorial(4); // == 24این مثال یک تابع D به نام "فاکتوریل" را مشخص می کند که به طور معمول در زمان اجرا ارزیابی می شود. استفاده از enum به کامپایلر می گوید که مقداردهی اولیه متغیرها باید در زمان کامپایل محاسبه شود. توجه داشته باشید که آرگومان های تابع باید در زمان کامپایل نیز دوباره حل شوند. 

از CTFE می توان برای جمع آوری ساختارهای داده در زمان کامپایل به روشی ساده استفاده کرد (نسخه D 2):int[] genFactorials(int n) {
  auto result = new int[n];
  result[0] = 1;
  foreach (i; 1 .. n)
    result[i] = result[i - 1] * i;
  return result;
}

enum factorials = genFactorials(13);

void main() {}

// 'factorials' contains at compile-time:
// [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 کامپایل می شوند.

منابع

پیوند به بیرون 
 نمونه های Rosettacode برای ارزیابی عملکرد زمان کامپایل به زبان های مختلف
بهینه‌سازی کامپایلر
کامپایلرسازی