编译时间功能评估(CTFE)如何工作?我试图理解编译器在运行时如何创建不存在的东西(例如,函数)并执行它。我习惯于通过编译将源代码变成二进制文件,然后执行二进制文件。那么,源代码如何在编译器运行时成为可执行的东西并且能够运行它?函数是否真的被创建和运行,或者它只是函数调用的模拟?
答案 0 :(得分: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
}
编译器经历了令牌化/ lexing /解析等常规阶段。当遇到enum compileTime(或任何其他需要编译时间值的构造)时,它将尝试评估表达式右侧的内容。在常量的情况下,它会执行您期望的并存储常量。如果遇到函数调用,它将启动CTFE解释器。在给定的示例中,它知道参数是什么,以及函数中的语句是什么,它逐步进行并解释每一个。如果它无法在编译时解释该语句,它将发出编译时错误。在这个简单的例子中,它只是否定了参数,但CTFE能够解释结构,类,循环等等,在此处记录 - http://dlang.org/function#interpretation。
答案 1 :(得分:1)
这本质上是constant folding的高级形式,其中编译器尝试计算使用的值,因此它不必在运行时发生(在编译时不会发生的操作(IO,内存分配,...... )会导致它失败)
CTFE的特殊之处在于它可以显式化(例如通过分配给enum
)并且它将尝试评估用户定义的函数
实际上,这可以通过编译器中的解释器构建来完成