如何理解在betterC模式下可以使用哪些功能?

时间:2017-09-05 09:18:31

标签: d

我正在尝试以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模式,如何通过功能理解?

1 个答案:

答案 0 :(得分: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数据段中的内存,因此不需要运行时分配,也不需要内存所有权管理(永远不会释放)。因此,他们在更好的C中工作。

但是,你问,canFind来自Phobos ......它没有链接!那么,为什么它不会产生错误呢?答案是因为它和它所依赖的一切(至少你传递的参数)是模板。因此,编译器会根据需要生成所有模板,并将其包含在您的exe中,而不是从库中引用它。大多数std.algorithm以这种方式工作......但是,特别是,如果你传递字符串参数,那就不行了!如果你传递一个字符串,它会尝试解码UTF数据(大错误,但在今天的点之后),这可以1)抛出异常和2)访问各种unicode库函数。所以他们会犯错误。你可以通过转换为字节来解决这个问题。

所以你不能依靠Phobos在betterC中工作,但是许多模板化程度很高的算法都可以工作,因为它们是按需生成的,只使用其他模板或C兼容的内置功能。<​​/ p >