D在17
年前就有了编译时
!D功能
稳步进入其他语言
.
:此处的编译时
关键字指示
在编译时运行它前面的块
.
D
不使用关键字
来触发它.触发它的是"常 式"
.当然,必须在编译时
可计算常
式.如:
int sum(int a, int b) => a + b;
void test()
{int s = sum(3, 4); //在运行时运行,enum e = sum(3, 4); //在编译时运行
}
只要避免使用非常全局变量
,I/O
和调用系统函数
(如malloc()
),无需更改
,可在编译时
运行相当大比例的函数
.
甚至可(使用D的自动管理内存
)用它分配内存
.
这是我最喜欢的用法之一
.我曾经编写一个单独的程序
来生成静态表
.用编译时执行函数
时,不再需要它了
.下面是一例
:
__gshared uint[256] tytab = tytab_init;
extern (D) private enum tytab_init =
() {uint[256] tab;foreach (i; TXptr) { tab[i] |= TYFLptr; }foreach (i; TXptr_nflat) { tab[i] |= TYFLptr; }foreach (i; TXreal) { tab[i] |= TYFLreal; }/*为简洁起见,删除了更多行*/return tab;
} ();
由计算数组
然后返回它的λ
返回'tytab'
数组的初化器
.
它的全部荣耀的链接.
CTFE
的另一个常见用法
是用来创建DSL
.
:感谢你创建D!
.
别客气!
:在每台x86
计算机上都是相同值?
它在所有机器
上都是相同值
,因为整数类型
是(不依赖实现
)固定大小
的,且2的补码算术
是强制性
的.
但是,因为计算常的顺序不同
,浮点结果
可能会有所不同
.如,x87
的计算精度
更高,然后仅在写入内存
时圆整它.
:我接着要感谢你制作D
.我仍没有找到一个我可以/会实际使用的
有更多编译时功能的语言
.所以我仍在使用D
.
有添加类似Zig
的setFloatMode(strict)
等的想法吗?我有1个或2个
项目想法,对某些计算,我需要确定性
然后是性能
.但仍非常需要浮点
所能提供的性能
.
谢谢你的客气话!
浮点确定性
的最佳选择
是坚持使用双精
.然后,在64
位代码中,使用坚持
使用64
位算术的XMM
寄存器和指令完成双精数学
运算.
实际上
,Zig
也允许这样做(在运行时
和编译时
环境中调用相同函数
):
fn square(num: i32) i32 {return num * num;
}
pub fn main() void {_ = square(2);_ = comptime square(3);
}
如果内容
与编译时
不兼容,则编译时
调用产生编译错误
(恕我直言,这是一个重要的功能
,因为如果期望在编译时
运行的代码因为某些输入参数
已按运行时求值
更改从编译时
,因此意外进入运行时
,它会敲响警钟
).
D的ImportC
也可用C代码
做CTFE
!
int sum(int a, int b) { return a + b; }
_Static_assert(sum(3, 4) == 7, "你看,编译时检查!");
为什么C标准
不添加它?它效果很好
!