d - 如何理解betterC模式下可以使用哪些函数?

标签 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模式?

最佳答案

如果您想使用-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/

相关文章:

d - D中函数之前的 "!"是什么意思

arrays - 如何使用 D2 的 phobos std.range 封装现有数组

d - 我可以指定最小配音或 DMD 版本吗?

java - 对于 Crestron/Extron,有 Java Lua D 语言的框架吗?

d - 在D中,私有(private)导入和普通导入有什么区别?

multidimensional-array - 有没有更好的方法来迭代多维数组?

d - 拆分/拆分的编译问题

d - 如何打印inout参数?

memory - 关闭 D 垃圾收集器

floating-point - 比较 D 中的 float