Jump to content

Compile-time function execution

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by 130.243.104.240 (talk) at 20:43, 21 December 2011 (Example). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Compile time function execution (or compile-time function evaluation, CTFE) is the ability of a compiler, that would normally compile a function to machine code and execute it at run-time, to execute the function at compile-time. This is possible if the arguments to the function are known at compile time, and the function does not make any reference to or attempt to modify any global state (is a pure function).

Even if the value of only some of the arguments are known, the compiler may still be able to perform some level of compile time function execution (partial evaluation), possibly producing more optimized code than if no arguments were known.

Example

In C++, template metaprogramming is often used to compute values at compile time, such as:

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
}

Using compile time function evaluation, code used to compute the factorial would be exactly the same as what one would write for run time evaluation. Here's an example of CTFE in the D programming language[1]:

int factorial(int n) {
    if (n == 0)
       return 1;
    return n * factorial(n - 1);
}

// computed at compile time
const int y = factorial(0); // == 1
const int x = factorial(4); // == 24

This example specifies a valid D function called "factorial" which would typically be evaluated at run time. The use of const tells the compiler that the initializer for the variables must be computed at compile time. Note that the arguments to the function must be able to be resolved at compile time as well.[2]

CTFE can be used to populate data structures at compile-time in a simple way (D version 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]


Example 2

  1. include<iostream>
  2. include<string>
  3. include<conio.h>
  4. include<sstream>
  5. include<cmath>
  6. include<fstream>
  7. include "Movie.h"

using namespace std;


cin.get(); eller getch(); alternativt system("PAUSE");








//main

  1. include<iostream>
  2. include<string>
  3. include<conio.h>
  4. include<sstream>
  5. include<cmath>
  6. include<fstream>

using namespace std;

  1. include "Movie.h"


void counter() { string line; ifstream infile; int count=0; infile.open("Filmer.txt"); if (infile.is_open()) {

   while ( !infile.eof() )
   {

getline( infile, line); count = count+1;

} count = count-1; cout << count << "st filmer finns i filen"; } infile.close(); }

void utfil() { string line; ifstream infile; infile.open("Filmer.txt"); if (infile.is_open()) { while ( !infile.eof() ) { getline( infile, line); cout << line; cout << endl; } } else cout << "Unable to open file"; infile.close(); }


void infil() { Movie a; a.read(); ofstream myfile; myfile.open ("Filmer.txt", ios::app); myfile << a << "\n"; myfile.close();

}


void testmovie() { Movie m, a, b("Fetfilmen" , "Tjockien" , 45);

if(b.gettitle() == "Fetfilmen") { cout << "getfunktioner funkar!\n"; }

a.settitle("Grizzlyfilmen");

if(a.gettitle() == "Grizzlyfilmen") { cout << "setfunktioner funkar!\n"; }

b.settitle("Grizzlyfilmen");

if(a == b) cout << "Compareoperatorn == funkar!\n";

}

void main1() {

Movie a, b("Glassfilm", "glassgubbe", 20);

a.settitle("Gubbfilm"); a.setactor("Gubben"); a.setduration(9000);

a.write();


}


void main2() {

Movie a, b;

a.read(); b.read();

a.write(); b.write();

if(a == b) cout << "a och b är samma film!"; else cout << "a och b är ej samma film";


}

void main3() {

Movie a("moviee", "apan", 2010);

cin>>a;

cout << a;


}


void main4() {

Movie a("moviee", "apan", 2010);

Movie b("moviee", "gurkan", 1212);


}

int main() { bool menu = true; int choice;

while(menu == true) { cout << "Vad vill du göra?\n" << "1.Add movie to archive 2.Read movies in archive 3.Test all functions 4.Count movies in archive 5.Exit 6.Delete all movies"; cin >> choice; switch(choice) { case 1: infil(); break;

case 2: utfil(); break;

case 3: testmovie(); break;

case 4: counter(); break;

case 5: menu = false; break;

case 6: remove("Filmer.txt"); ofstream output("Filmer.txt"); break;



} }


getch();

return 0;

}


//hfil

  1. include <iostream>
  2. include <string>
  3. include <istream>

using namespace std;


class Movie {

private: string title; string actor; int duration;

public: Movie() //constructor utan parametrar { title = ""; actor = ""; duration = 0; }

Movie(string title, string actor, int duration) //constuctor med parametrar { this->title = title; this->actor = actor; this->duration = duration;

}

string gettitle() {return title;} void settitle (string t) {title = t;}

string getactor(){return actor;} void setactor(string a){actor = a;}

int getduration() {return duration;} void setduration (int d){duration = d;}

friend ostream& operator<< (ostream& o, const Movie& Movie) { o << "("; o << Movie.title; o << ","; o << Movie.actor; o << ","; o << Movie.duration; o << ")";


return o; }


friend istream& operator>> (istream &i, Movie& Movie) { char c; i >> skipws >> c; getline(cin, Movie.title, ','); i >> skipws; getline(cin, Movie.actor, ','); i >> skipws; i >> skipws >> Movie.duration; i >> skipws >> c;

return i;

}


friend int operator== (const Movie m1, const Movie m2) {

if ( m1.title == m2.title )

return 1; else return 0; }


void read() { string c; cout<< endl << "Enter movie name: "; cin >> c; getline(cin, this->title, '\n'); this->title = c + this->title; cout << endl; cout<< "Enter actor name: "; getline(cin, this->actor, '\n'); cout << endl;

cout<< "Enter duration: "; cin >> duration; cout << endl;

}

void write() { cout << "Title: " << title << endl; cout << "Actor: " << actor << endl; cout << "Duration: " << duration << endl; }





};

References