gpt4 book ai didi

function - D 函数返回自动引用

转载 作者:行者123 更新时间:2023-12-02 15:18:17 25 4
gpt4 key购买 nike

函数的返回类型 auto ref 是什么意思?我只是不理解它。我从 Ali Çehreli 的在线书籍中拿了一个例子,并尝试以各种方式对其进行改编,并查看了 GDC 生成的汇编器,但我仍然没有真正变得聪明。 (我是一位非常有经验的 asm 和 C 程序员,但刚接触 D。)您什么时候真正需要使用此功能?

最佳答案

auto 返回函数的主要用例是在模板中,其中函数体根据某些编译时参数发生变化。 auto ref 只是将其扩展为允许 ref 返回。看:

auto ref foo(string magic)() {
static if(magic == "use ref") {
int* x = new int;
return *x;
} else {
return 0;
}
}

void main() {
foo!""();
foo!"use ref"();
}

每组独特的编译时参数将生成不同的函数。这些不同的函数具有完全不同的代码。

这是一个带有空字符串的函数:

Disassembly of section .text._D3iii15__T3fooVAyaa0_Z3fooFNaNbNiNfZi:

00000000 <_D3iii15__T3fooVAyaa0_Z3fooFNaNbNiNfZi>:
0: 31 c0 xor eax,eax
2: c3 ret
3: 90 nop
4: 90 nop
5: 90 nop
6: 90 nop
7: 90 nop

如您所见,这是最简单的 - return 0。没有花哨的裁判返回那里。这是带有 use ref 的那个:

Disassembly of section .text._D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi:

00000000 <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi>:
0: 55 push ebp
1: 8b ec mov ebp,esp
3: b8 00 00 00 00 mov eax,0x0
8: 50 push eax
9: e8 fc ff ff ff call a <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNcNfZi+0xa>
e: 83 c4 04 add esp,0x4
11: 5d pop ebp
12: c3 ret
13: 90 nop
14: 90 nop
15: 90 nop
16: 90 nop
17: 90 nop

(损坏的名称中有字符串作为 ascii 的十六进制字符串(好吧,它实际上是 UTF-8,unicode 也可以!)字节顺便说一句,75736520726566 部分 - 将 0x75 识别为“u”,将 0x66 识别为'f'。D 错位的名称可能会长得离谱,但一旦您了解它,该模式就非常容易阅读。)

那段代码调用了 new,所以主体更复杂,但请注意 eax 仍然在那里保存返回值……指针。现在,让我们从 auto ref 中取出 ref 并重新编译相同的东西。

当然,第一个功能保持不变。第二个改变了:

Disassembly of section .text._D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi:

00000000 <_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi>:
0: 55 push ebp
1: 8b ec mov ebp,esp
3: b8 00 00 00 00 mov eax,0x0
8: 50 push eax
9: e8 fc ff ff ff call a<_D3iii29__T3fooVAyaa7_75736520726566Z3fooFNaNbNfZi+0xa>
e: 8b 00 mov eax,DWORD PTR [eax]
10: 83 c4 04 add esp,0x4
13: 5d pop ebp
14: c3 ret
15: 90 nop
16: 90 nop
17: 90 nop

看到 mov eax,DWORD PTR [eax]了吗?它不再返回指针(这当然是 ref return 在幕后所做的),但现在它指向的是一个正常的、非 ref 的值返回。

这就是auto return 和auto ref 的区别。

为了完整起见,让我们将其更改为ref int,看看会发生什么:

$ dmd iii
iii.d(6): Error: constant 0 is not an lvalue
iii.d(11): Error: template instance iii.foo!"" error instantiating

现在只返回 0 是错误的,因为那不是有效的 ref

实际用例是,模板可能会根据各种参数做出更复杂的决定,决定在它们的主体中做什么,以及它们的返回类型。它可能只是返回传递给它的参数的任何类型,它可能会检查平台版本(那将是一些丑陋的代码大声笑),等等。 auto ref 允许您涵盖各种类似的情况,而无需自己编写单独的函数签名(以及函数体)。

关于function - D 函数返回自动引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39041609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com