2017-09-05 80 views
2

我試圖編譯下面的代碼在betterC模式:如何理解哪些功能可以在betterC模式下使用?

import core.stdc.stdio; 
import std.algorithm; 

extern(C): 
int main() 
{ 
    int [] x = [1,2,3,4,5]; 

    if(x.canFind(3)) 
     printf("Good"); 
    else 
     printf("Bad"); 

return 0; 
} 

在此代碼,我得到了鏈接錯誤。所以似乎canFind不能在這裏使用。

如何通過函數了解它是否適​​用於betterC模式?

回答

3

如果您想使用-betterC,您需要了解如何閱讀鏈接器錯誤消息。該代碼不會生成關於canFind的任何內容......它實際上是數組文字。

ppp.o: In function `main': 
ppp.d:(.text.main[main]+0x8): undefined reference to `_D11TypeInfo_Ai6__initZ' 
ppp.d:(.text.main[main]+0xe): undefined reference to `_d_arrayliteralTX' 

製作陣列static它會起作用。

那麼,爲什麼? betterC的規則是,它只適用於不需要D運行時庫的事情。它沒有鏈接它(所以任何引用運行時函數的函數都會導致鏈接器錯誤),爲某些D特性生成C選項(特別是在betterC中聲明使用C lib版本而不是D lib版本),以及不會生成其他需要它的代碼(因此沒有TypeInfo,任何試圖使用它的代碼都會導致鏈接器錯誤)。

缺乏druntime鏈接解釋了爲什麼這是一個錯誤:非靜態數組文字是運行時庫函數的語法糖(恰好將它分配到GC堆中,因此您可以共享它們的片段而不用擔心所有權)。因此,它們會導致betterC中的鏈接器錯誤。

靜態數組只是exe的數據段中的內存,所以不需要運行時分配,也不需要內存所有權管理(它永遠不會被釋放)。因此,他們在betterC工作。

但是,請問,canFind來自沒有鏈接的Phobos ...!那麼,爲什麼它不會產生錯誤呢?答案是因爲它和它所依賴的一切(至少是你傳遞的參數)都是模板。因此,編譯器按需生成所有模板,並將其包含在exe文件中,而不是從庫中引用它。 std.algorithm大部分都是這樣工作的......但是,值得注意的是,如果你傳遞它的字符串參數不行!如果你傳遞一個字符串,它會嘗試解碼UTF數據(大錯特徵,但在今天這一點),它可以1)拋出異常,2)訪問各種unicode庫函數。所以他們會犯錯。您可以通過轉換爲字節來解決此問題。

所以你不能依靠Phobos在betterC上工作,但許多重要模板化的算法都可以工作,因爲它們是按需生成的,只能使用其他模板或C兼容的內置功能。

相關問題