8

编译时函数评估 (CTFE) 如何工作?我试图了解编译器在运行时如何创建不存在的东西(例如函数)并执行它。我习惯了源代码通过编译成为二进制文件,然后执行二进制文件的想法。那么,源代码如何在编译器运行并且能够运行时变成可执行的东西呢?一个函数是否真的被创建并运行,或者它只是一个函数调用的模拟?

4

2 回答 2

11

CTFE 使用编译器中内置的解释器 - 就像您对 Python 等解释语言所期望的一样。当你编译这样的东西时:

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
}

编译器会经历标记化/词法分析/解析等通常阶段。当遇到 enum compileTime(或任何其他需要编译时间值的构造)时,它将尝试评估表达式右侧的内容。在常量的情况下,它会执行您期望的操作并存储常量。如果遇到函数调用,它将启动 CTFE 解释器。在给定的示例中,它知道参数是什么,以及函数中的语句做什么,它一步一步地完成并解释每一个。如果它无法在编译时解释该语句,它将发出编译时错误。在这个简单的例子中,它只是否定了参数,但是 CTFE 能够解释结构、类、循环等等,记录在这里 - http://dlang.org/function#interpretation.

于 2012-04-22T14:53:05.853 回答
1

这本质上是一种高级形式的常量折叠,其中编译器尝试计算使用的值,因此它不必在运行时发生(在编译时不能发生的操作(IO,内存分配,...)将导致它失败)

CTFE 的特殊之处在于它可以显式化(通过分配给一个enum例子)并且它会尝试评估用户定义的函数

在实践中,这可以通过编译器中的解释器来完成

于 2012-04-23T17:35:48.157 回答