d的betterC简介.
原地址
作者:W.B(D作者)
d一开始就设计为,与c直接交互,与c++轻量交互.这样可访问无穷的c库,标准c运行时库及操作系统接口(一般也是c.有大量c编写的程序.d可对接c,但c不行.d必须要控制主函数,这也是更好的c.其实c++就是曾经更好的c.早期c++编译器可编译c.这推动了c++的成功.同样的还有kotlin.成为更好的java.
d的方法是,既不是c的扩展,也不是c的超集,也不带c的问题(预处理器/数组溢出),而是子集化d语言.删除/改变要求d启动及运行时的库.即-betterC开关.
保存了d的核心语言能力,结果是c与d间,但完全向上兼容d的语言.
最明显区别是删除了Gc,及依赖他的东西.可用与c一样的方式分配内存,用malloc或自定义.尽管c++类/com类仍然可用,但d类是不行的.异常,typeid,静态构造/析构都去掉了.断定调用c版本的.
还剩下:内存安全,模块,函数重载,构造函数,成员函数,统一码,嵌套函数,动态闭包,编译时函数执行,自动生成文档,高级元编程和自省设计
考虑一下c:
#include <stdio.h>
int main(int argc, char** argv) {
printf("hello world\n");
return 0;
}
编译为:
_main:
push EAX
mov [ESP],offset FLAT:_DATA
call near ptr _printf
xor EAX,EAX
pop ECX
ret
23kb,转为d:
import core.stdc.stdio;
extern (C) int main(int argc, char** argv) {
printf("hello world\n");
return 0;
}
一样大.这不奇怪,因为c/d共享相同编译器.即使用d无须付费.来看个复杂的筛法程序.
#include <stdio.h>
#define true 1
#define false 0
#define size 8190
#define sizepl 8191
char flags[sizepl];
int main() {//筛法
int i, prime, k, count, iter;
printf ("10 iterations\n");
for (iter = 1; iter <= 10; iter++) {
count = 0;
for (i = 0; i <= size; i++)
flags[i] = true;
for (i = 0; i <= size; i++) {
if (flags[i]) {
prime = i + i + 3;
k = i + prime;
while (k <= size) {
flags[k] = false;
k += prime;
}
count += 1;
}
}
}
printf ("\n%d primes", count);
return 0;
}
上面是c,下面是d,对比下:
import core.stdc.stdio;
extern (C):
__gshared bool[8191] flags;
int main() {
int count;
printf("10 iterations\n");
foreach (iter; 1 .. 11) {
count = 0;
flags[] = true;
foreach (i; 0 .. flags.length) {
if (flags[i]) {
const prime = i + i + 3;
auto k = i + prime;
while (k < flags.length) {
flags[k] = false;
k += prime;
}
count += 1;
}
}
}
printf("%d primes\n", count);
return 0;
}
看起来一样,但要注意:
extern (C),表明c调用传统.D一般把静态数据放在线程本地存储中,但可用__gshared来实现c一样的全局数据.
foreach用来循环.flags[] = true一趟赋值所有.
常表明不会变.自动推导iter, i, prime和k的类型,用flags.length给出长度.
访问flags,自动检查边界.无溢出错误.一切自动完成.d改善了c的可读性,安全性,表达性.有了d,如嵌套函数,你可能不再需要到处goto了.
d的更好C,真的不错.你可以将c改为d,然后就不用c了.
纯函数,不能修改全局状态.输入出都在函数签名中.D无法编译c,你得稍微修改下.如->改为..
浙公网安备 33010602011771号