2017-10-21 118 views
1

此代码与合同:ldc和gdc是否支持D语言合约?

import std.stdio; 

int TestContract(int a) 
in 
{ 
    assert(a > 0); 
} 
do 
{ 
    return a + 1; 
} 

int main(string[] args) 
{ 
    auto a = 2; 
    try 
    { 
     writeln(a," + 1 is ",TestContract(a)); 
     a = -2; 
     writeln(a," + 1 is ",TestContract(a)); 
    } 
    catch (Exception e) 
    { 
     writeln(e); 
    } 
    return 0; 
} 

编译并用DMD(v2.076.0脏),但不LDC(0.17.1)或GDC(5.4.0 20160609)中运行。

LDC说:

contracts.d(12): Error: declaration expected, not 'do' 
contracts.d(15): Error: unrecognized declaration 

和GDC说:

contracts.d:12:1: error: declaration expected, not 'do' 
do 
^ 
contracts.d:15:1: error: unrecognized declaration 
} 

编辑:用 “身体” 编译,而不是 “做”,每答案与最不发达国家成功。 GDC得到一个新的编译错误:

/usr/include/d/core/stdc/stdarg.d:48:5: error: undefined identifier __va_list_tag 
    alias __va_list = __va_list_tag; 

注意,在目前的时间为contract programming的dlang.org文件没有提到身体,而可能过时,仍然有效,而且是必要的DMD的版本早于[未知版本]的编译器以及在版本[未知版本]之前使用dmd前端的任何版本的gdc或ldc。

+0

ldc(0.17.5)为我工作,使用'do'而不是'body'。并且dmd(2.077.0)也可以工作,这并不奇怪。 – Eljay

回答

2

使用body而不是do。允许do而不是body是一个非常近的事情(我不知道这个改变甚至被接受了,尽管它与当前的dmd编译,所以我猜是这样)。

dmd,ldc和gdc都共享相同的前端,但它们并不都具有相同的版本。即使你使用的是最新的ldc,它至少有一个,也许是dmd后面的两个版本,除非你使用的是gdc的开发版本,它现在是的方式(它在2.068 IIRC,而dmd 2.077。 0目前处于测试阶段),但他们所做的下一个版本应该最终与dmd相当接近(从C++到D的前端开关会导致它们的重大延迟)。

+0

谢谢。他们可能应该在文档页面上显示正文 - “23.合同编程”。 LDC可以处理正文,GDC得到一个关于__va_list_tag的新错误 – Scooter

+0

有人不喜欢使用'body'可能会急切地更新文档,当切换到'do'的DIP和从'body'作为关键字时移开公认。我不知道gdc为什么会失败,但正如我所说的,除非你使用的是开发版本,否则它是相当古老的。 –

+0

gdc(5.4.0 20160609)。此版本号表明您使用的是gdcproject.org的二进制版本?然后,druntime源不应位于'/ usr/include/d/core/stdc/stdarg.d'中,可能属于LDC或DMD。 GDC总是在'/ usr/include/d'中搜索额外的D文件,所以你不应该在那里放置编译器特定的包含文件(druntime,phobos)。 – jpf

2

是的,ldc和gdc都支持合同。这是一种最近的语言变化 - 在合同中替换dobody并编译。你应该时刻注意你正在使用相同的D前端版本。例如,ldcldc2 --version表示。

+1

这与LDC一起工作,但我得到与gdc不同的错误(5.4.0 20160609)。本来会尝试过的,但“23.合约编程”只显示“做”。我认为应该加回“身体”。 – Scooter

+2

更改原因如下:https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md。我同意文档应该提及'body'关键字已被弃用。 –