我正在尝试以 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
模式?
最佳答案
如果您想使用-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'
将数组设置为静态
,它将起作用。
嗯,为什么? 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 兼容的内置功能。</p>
关于d - 如何理解betterC模式下可以使用哪些函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46051347/