??xml version="1.0" encoding="utf-8" standalone="yes"?> Dec 1, 2005
akIDE是一个D语言的IDEQ可以到http://www.lessequal.com/akide下蝲Q它只需要DMD支持?BR>
C++ ABI Summary
http://www.codesourcery.com/cxx-abi/
C++ ABI for IA-64: Code and Implementation Examples
http://www.codesourcery.com/cxx-abi/abi-examples.html
C++ Vtable Example
http://www.codesourcery.com/cxx-abi/cxx-vtable-ex.html
Intel] Itanium] Processor-specific Application Binary Interface (ABI)
http://developer.intel.com/design/itanium/downloads/245370.htm
]]>New/Changed Features
Bugs Fixed
其中“D代码覆盖分析器”应该是很多人感兴趣的东西了Q下面是一个例?摘自http://digitalmars.com/d/code_coverage.html)Q?/P>
bit flags[8191];
int main()
{ int i, prime, k, count, iter;
printf("10 iterations\n");
for (iter = 1; iter <= 10; iter++)
{ count = 0;
flags[] = true;
for (i = 0; i < flags.length; i++)
{ if (flags[i])
{ prime = i + i + 3;
k = i + prime;
while (k < flags.length)
{
flags[k] = false;
k += prime;
}
count += 1;
}
}
}
printf ("\n%d primes\n", count);
return 0;
}
~译、运行:
sieve
|
|bit flags[8191];
|
|int main()
5|{ int i, prime, k, count, iter;
|
1| printf("10 iterations\n");
22| for (iter = 1; iter <= 10; iter++)
10| { count = 0;
10| flags[] = true;
163840| for (i = 0; i < flags.length; i++)
81910| { if (flags[i])
18990| { prime = i + i + 3;
18990| k = i + prime;
168980| while (k < flags.length)
| {
149990| flags[k] = false;
149990| k += prime;
| }
18990| count += 1;
| }
| }
| }
1| printf ("\n%d primes\n", count);
1| return 0;
|}
sieve.d is 100% covered
另一个惊喜是mangleof属性,可以得到一个类型被~译器mangle后的名字。不知道mangle对应的中文翻译是什么?大概是“名字{换”吧。一Ҏ试代码:
void test();
void test1(int n);
void test2(int n);
void main()
{
void function (int, char[]) f;
void function (int) f1;
void function () f2;
writefln (f.mangleof);
writefln (f1.mangleof);
writefln (f2.mangleof);
writefln (int.mangleof);
float a;
writefln (a.mangleof);
writefln ((&test).mangleof);
writefln ((&test1).mangleof);
writefln ((&test2).mangleof);
writefln (void.mangleof);
}
PFiZv
PFZv
i
f
PFZv
PFiZv
PFiZv
v
]]>New/Changed Features
Bugs Fixed
比较感兴的是QҎ和字W串帔R作ؓ模板值参敎ͼ单测试了一下:
template TFloat (float F)
{
float value = F;
}
template TString (char[] S)
{
char[] value = S;
}
void main()
{
alias TFloat!(3.14f) PI;
writefln(PI.value);
writefln(TString!("hello").value);
}
~译通过Q运行结果如下:
3.14
hello
]]>
另外2个符合ECMA 262规范的脚本语a分别是Netscape的javascript和Microsoft的JScriptQ目前DMDScript和其?个不完全兼容Q不q效率要高一些。DMDScript提供了一个简单的试Q生?190以内的质敎ͼq代10ơ,在我的机器上Qjavascript执行耗时566毫秒QDMDScript执行耗时188毫秒Q整整快?倍?BR>
如果你想实现一个符合ECMA 262标准的脚本语aQ徏议看q䆾代码的实现吧Q比较简z,只有400多K。微软那份估计是很难看到了,Netscape那䆾用C写的Q代码大就有近3MQ宏也比较多Q看h要吃力一些?BR>
DDL是dsource.org上的一个有的目Q它可以?obj?lib文g中加载代码ƈ执行Q目前支持COFF、OMF、ELF格式?img src ="http://www.shnenglu.com/cpunion/aggbug/1200.html" width = "1" height = "1" />
]]>
闲话说Q请看代码:
template DelegateHandlers(HandlerType, FunctionType)
{
HandlerType[] handlers;
FunctionType[] functions;
void opAddAssign(HandlerType h)
{
handlers.length = handlers.length + 1;
handlers[length-1] = h;
}
void opAddAssign(FunctionType f)
{
functions.length = functions.length + 1;
functions[length-1] = f;
}
}
template Delegate(Ret)
{
class Delegate
{
alias Ret delegate () HandlerType;
alias Ret function () FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall ()
{
foreach (HandlerType handler; handlers)
handler ();
foreach (FunctionType _function; functions)
_function ();
}
}
else
{
Ret opCall ()
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler ();
foreach (FunctionType _function; functions)
ret = _function ();
return ret;
}
}
}
}
template Delegate(Ret, Arg1)
{
class Delegate
{
alias Ret delegate (Arg1) HandlerType;
alias Ret function (Arg1) FunctionType;
mixin DelegateHandlers!(HandlerType, FunctionType);
static if(is(Ret: void))
{
void opCall (Arg1 a1)
{
foreach (HandlerType handler; handlers)
handler (a1);
foreach (FunctionType _function; functions)
_function (a1);
}
}
else
{
Ret opCall (Arg1 a1)
{
Ret ret;
foreach (HandlerType handler; handlers)
ret = handler (a1);
foreach (FunctionType _function; functions)
ret = _function (a1);
return ret;
}
}
}
}
class Test
{
void test ()
{
writefln ("Test.test");
}
int test1 ()
{
writefln ("Test.test1");
return 1;
}
void test2(int v)
{
writefln ("Test.test2");
}
int test3(int v)
{
writefln ("Test.test3");
return 7;
}
}
void test_func ()
{
writefln ("test_func");
}
int test_func1 ()
{
writefln ("test_func1");
return 2;
}
void test_func2(int v)
{
writefln ("test_func2");
}
int test_func3(int v)
{
writefln ("test_func3");
return 9;
}
void main()
{
Test t = new Test;
alias Delegate!(void) DDD;
DDD d = new DDD;
d += &t.test;
d += &test_func;
d ();
alias Delegate!(int) DDD1;
DDD1 d1 = new DDD1;
d1 += &t.test1;
d1 += &test_func1;
int a = d1 ();
assert (a == 2);
alias Delegate!(void, int) DDD2;
DDD2 d2 = new DDD2;
d2 += &t.test2;
d2 += &test_func2;
d2 (1);
alias Delegate!(int, int) DDD3;
DDD3 d3 = new DDD3;
d3 += &t.test3;
d3 += &test_func3;
int b = d3 (2);
assert (b == 9);
}
非常q净Q非常简z,不是吗?q个只花了我10分钟旉来写。。?BR>
D语言的委托非帔R效,有兴的可以试一下通过委托和直接调用之间的性能差别。上面这个自己实现的多分z֧托类Q效率也非常高,我的试l果是对于性能的媄响几乎可以忽略。想起那个历千辛万苦实现的CQ+多分z֧托类Q实现复杂、调试费时、运行效率还很低Q每每一惛_q心里那个难受啊。。。?BR>
再来看一下D语言强大的静态检查机Ӟ
{
int n = v;
static assert (v > 3);
}
void main ()
{
int n;
n = XXX!(4).n; // OK
n = XXX!(3).n; // ~译错误
}
同样很漂亮?BR>
如果你觉得提CZ息不够友好,可以修改为:
{
int n = v;
static if (v <= 3)
pragma (msg, "template value must > 3");
static assert (v > 3);
}
q是~译时的错误提示Q?BR>
Compiling test.d ...
template value must > 3
D:\workspace\dace\test.d(94): static assert (3 > 3) is false
D:\workspace\dace\test.d(173): template instance test.XXX!(3) error instantiating
我想以后有可能会扩充pragmaQ支持错误输出,q样׃用写重复的语句了Q可以简化成q样Q?BR>
{
int n = v;
static if (v <= 3)
pragma (error, "template value must > 3");
}
q样看v来更好。不q目前有很多重要Ҏ要实现Q这U玩意可能要很久以后才会加入了?img src ="http://www.shnenglu.com/cpunion/aggbug/1083.html" width = "1" height = "1" />
]]>
]]>
void test(int a, inout int b, out int c)
{
writefln(a);
writefln(b);
writefln(c);
a = 3;
b = 5;
c = 7;
}
void main ()
{
int a = 0, b = 1, c = 2;
test(a, b, c);
assert (a == 0);
assert (b == 5);
assert (c == 7);
std.process.system("pause");
}
在上面的例子里,E序在test函数中的输出语句输出:
0
1
0
也就是说Qout参数取值是无意义的Q它只用于赋倹{?BR>
q里有一个很大的问题Q调用test(a,b,c)Ӟ调用者对于c的D改变可能毫无知觉Q甚x为隐藏很qBUG。对此,许多人徏议加强检查,比如在调用时Q必L明inout/outQ?BR>
g能够起到一些警CZ用,不过q样一来,语法上倒不怎么l了?img src ="http://www.shnenglu.com/cpunion/aggbug/1044.html" width = "1" height = "1" />
]]>
writefln(a);
char b = "abcde"[3];
writefln(b);
另外修复了一些编译器和文生成的BUG?BR>
v0.137的重要更新有Q?BR>隐式cd引用Q?BR>
{
extern(C) test1();
}
其它更新则主要集中于~译器工作、文工兗库{,暂时q没有特别o人兴奋的Ҏ加入进来,比如Qstack tracing, relation api{?img src ="http://www.shnenglu.com/cpunion/aggbug/1039.html" width = "1" height = "1" />
]]>
2、好用的字符串常量表辑ּ?BR>除了cC的用双引号的字W串帔R表达式以外,q可以用`字符。可以用x"68 65 6C6C 6F"来表C?hello"Qr"ab\na"则忽略字W串帔R中{义字W的转义作用Q还可以在字W串帔R后加上c, w或d来指C字W串帔R是char[]cd、wchar[]cdq是dchar[]cd。可以用~q算W连?个字W串?BR>
3、数字?BR>数字可以直接使用Q还可以q样来定义:int a = 3_029_301_000; 数字直接?包括整数、QҎ、复?表达式中Q“_”字W是被忽略的。另外还直接提供了复数类型?BR>
4、提供定长数l、变长数l、关联数l?BR>int[3] a定义一个定长数l;int [] a定义一个变长数l;int[int]定义一个关联数l,键类型是intQ值类型是intQint[char[]] a定义一个关联数l,键类型是char[]Q值类型是intQ用非常方ѝ?BR>可以使用foreach来遍历数l:
foreach (int index, int value; a)
printf ("%d: %d\n", index, value);
foreach (char[] key, int value; a)
printf ("%.*s: %d\n", index, value);
可以使用in操作W来判断某个值是否是兌数组的一个键Q?BR>
int[char[]] a;
if ("hello" in a)
writefln ("hello");
数组可以切片(slice)Q?BR>
int[] a;
int[] b = a[1..3];
int[] c = a[1..length];
{等。。。?BR>
5、其它还支持委托、函数指针、模ѝ异常、RAII、契U式~程、单元测试、with语句、auto/typeof、垃圑֛收、操作符重蝲、内联汇~、条件编译、嵌入到HTML{,它还标准化了ABI(q是C/C++最让h头痛的地方之一)。这些特性大部分都比较熟悉和实用Q下面简单介l一下条件编译和嵌入到HTML?BR>
6、条件编译?BR>在D中,可以使用version(VersionID)来进行条件编译:
{
//
}
else
{
//..
}
q可以用debug条gQ?BR>
{
//
}
else
{
//
}
或者:
debug printf ("hello");
静态条件编译:
static if (n == 1)
writefln ("hello");
else
writefln ("world");
cd查:
if (is(n[]))
writefln ("like array");
if (is(n:int))
writefln ("is an integer");
7、嵌入HTML?BR>在一个HTML文g中,<code>?lt;/code>之间的部分可以当作D代码来编译。比如下面这D代码:
<code>
import std.c.stdio;
int <font size=+1><b>main</b></font>()
{
<span style="color:red">printf</span>(<u>"hello world\n"</u>);
return 0;
}
</code>
<hr />
<h1> End </h1>
把它存储为HTML文gQ可以直接用dmd~译器编译?img src ="http://www.shnenglu.com/cpunion/aggbug/902.html" width = "1" height = "1" />
]]>
D语言的介l最好是?A >uframer的blogQ他译了D语言的大部分文。当然由于D语言目前一直处于测试版Q文和最新的~译器之间可能有很多不一致?BR>
D语言的编译器目前?个,DMD和GDCQDMD比较Ҏ配置Q可以从http://www.digitalmars.com/d/dcompiler.html下蝲最新版。下载的压羃包直接解压到L一个分区的根目录,q把\dm\bin和\dmd\bin加到PATH环境变量里即可用?BR>
写一个简单的D语言E序Q当然还是经典的HelloWorldE序Q?BR>
{
printf ("Hello world!\n");
}
和CE序基本上一栗把它保存ؓhello_world.d?BR>
下面直接在这个源文g所在的目录下,执行dmd hello_world.dQ即可编译出hello_world.exeQ执行它p在控制台打印出Hello world!?BR>
接下来到http://www.dsource.org/projects/build/下蝲buildE序Q这是在DC使用比较q泛的一个程序。由于最新的v2.09版已l发C一些严重的BUGQ所以最好到http://svn.dsource.org/projects/build/downloads/下蝲v2.08版。把下蝲?exe文g改名为build.exeq放|合适的文g夹下Qƈ讄PATH环境变量?为简单v见我是直接把它放在\dm\bin文g夹下)
下面试一下buildE序Q编写一个hello_world.brf文gQ保存在hello_world.d同一路径下,文g内容如下Q?BR>
hello_world.d
然后执行build @hello_world卛_~译出hello_world.exe?/P>
D语言~译速度非常?q也是Walter Bright对C++不满的一个重要原?。dsource.org中的mango目包含755个D源文Ӟ但在我的机器上编译成.lib文g只需?U时间?BR>
D语言性能也很不错Q有2D语言和C/C++、Java、C#的性能比较文章Q?A >
http://mag.vchelp.net/200312/fanyi.htm
http://mag.vchelp.net/200312/fanyi_2.htm
相关目介绍Q?BR>mango: q是一个专注于服务端编E的目Q目前主要由Kris开发、维护,实现了servletQ暂时还没有太复杂的功能Q不q很值得期待?BR>dwt: D语言的swt开发包Q界面开发首选。看qeclipse界面的应该有比较q印象。由于大部分代码是从java代码转换q来的,所以类名、接口等都没有改变?BR>dui: D语言的别一个界面开发包Q基于GTK?BR>build: 上面介绍q的build工具?BR>dcoder: Zvs.net的D语言语法高亮插g?BR>dsp: 全称是Dynamic Servlet Pages?BR>
以上目都可以在http://www.dsource.org/projects/扑ֈ详细资料?BR>
DMDScript是一个类gJavaScript的脚本系l,可以?A >http://www.digitalmars.com/dscript/扑ֈ详细资料Q这个我q没有用过?BR>
最后附?个用dwt开发的界面(注:׃本h不习惯安装杀毒YӞ下蝲请先杀?Q?/FONT>
1、仿eclipse界面Q?BR>http://www.shnenglu.com/Files/cpunion/dummyeclipse.rar
2、dwt控g演示Q?BR>http://www.shnenglu.com/Files/cpunion/controlexample.rar
在windows xp主题下效果比较好。这2个程序在我的机器上分别只?.4M?.2M内存Q启动时间也不1U,不要被eclipse的启动时间吓坏了?BR>
扑ֈ了这2张图Q?BR>
2、要深入学习antlr?BR>很多时候,~程语言不是领域描述的最佌aQ需要找一个或~写一个{换工兗?BR>antlr可以帮我们实C个自pa的词法分析程序,而不需要忍受yacc生成的天书代码?/P>
3、lua和boost::python?BR>大致看了一下它们包装CQ+cȝ方式Q有点相伹{?BR>我打做一个CQ+语言的轻量分布式包装库Q有些地方可以参考?/P>
4、prolog?BR>满好玩的东西?/P>