How does Compile Time Function Evaluation (CTFE) work? I'm trying to understand how the compiler, while it's running, creates something that doesn't exists (e.g., a function) and executes it. I'm used to the idea that source code becomes a binary file through compilation, and then the binary is executed. So, how does a source code become something that's executable while the compiler is running and it's able to run it? Does a function really get created and run, or is it just an emulation of a function call?
CTFE uses an interpreter that's build into the compiler - much like what you'd expect from an interpreted language such as Python. When you compile something like this:
bool not(bool arg) {
return !arg;
}
void main() {
enum compileTime = not(true); // not() called at compile time
bool runTime = not(true); // not() called at runtime
}
The compiler goes through the usual stages of tokenising/lexing/parsing and so on. When enum compileTime is encountered (or any other construct which requires a compile time value), it will try to evaluate what is on the right hand side of the expression. In the case of a constant it does what you would expect and stores a constant. If it encounters a function call, it will start the CTFE interpreter. In the given example, it knows what the arguments are, and what the statements in the function do, it goes through step by step and interprets each one. If it can't interpret the statement at compile time it will issue a compile time error. In this simple example, it just negates the parameter, but CTFE is capable of interpreting structs, classes, loops and much more, documented here - http://dlang.org/function#interpretation.
this is essentially an advanced form of constant folding where the compiler tries to compute values used so it doesn't have to happen at runtime (operations that cannot happen at compile time (IO, memory alloc,...) will cause it to fail)
CTFE is special in that it can be made explicit (by assigning to an enum
for example) and that it will attempt to evaluate user-defined functions
in practice this can done by an interpreter build in the compiler
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With