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