2017-10-21 303 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'關鍵字已被棄用。 –