gpt4 book ai didi

c - __fastcall 与注册语法?

转载 作者:太空宇宙 更新时间:2023-11-04 00:06:31 26 4
gpt4 key购买 nike

目前我有一个小函数,它被调用非常非常频繁(循环多次),接受一个参数。因此,这是 __fastcall 的一个很好的例子。

虽然我想知道。

这两种语法有区别吗:

void __fastcall func(CTarget *pCt);

void func(register CTarget *pCt);

毕竟,这两种语法基本上告诉编译器将参数传递到寄存器中,对吗?

谢谢!

最佳答案

__fastcall 定义了一个特定的约定。

它首先由 Microsoft 添加以定义一个约定,其中适合 ECXEDX 寄存器的前两个参数放在它们中(在 x86 上,在x86-64 关键字将被忽略,尽管使用的约定已经使寄存器的使用更加频繁)。

其他一些编译器也有 __fastcallfastcall。海湾合作委员会与微软一样多。 Borland 使用 EAXEDXECX

Watcom 识别兼容性关键字,但忽略它并使用 EAXEDXEBXECX不管。事实上,正是相信这一约定是 Watcom 很久以前在多个基准测试中击败微软的原因,这导致了 __fastcall 的发明。 (因此 MS 可以产生类似的效果,而默认值将与旧代码保持兼容)。

_mregparam 也可以与某些编译器一起使用,以更改使用的寄存器数量(Linux 内核的某些版本在 Intel 或 GCC 上,但使用 _mregparam 3 以便导致与 Borland 上的 __fastcall 类似的结果。

值得注意的是,最先进的技术在许多方面都在进步,(CPU 中发生的缓存特别相关)__fastcall 实际上在某些情况下可能比其他约定慢.

以上都不是标准的。

同时,register 是一个标准关键字,最初定义为“如果可能,请将其放入寄存器”,但更一般的意思是“永远不会使用此自动变量或参数的地址。请使在优化中使用它,尽你所能”。这可能意味着注册值,它可能被忽略,或者它可能用于一些其他编译器优化(例如,事实地址不能被采用意味着某些类型的别名错误不会发生某些优化)。

通常,它在很大程度上被忽略了,因为编译器可以判断您是否获取了地址并仅使用该信息(或者确实有一个内存位置,复制到寄存器中以进行一堆或工作,然后在地址之前复制回来用来)。相反,它可能在函数签名中被忽略只是为了让约定保持约定(特别是如果导出,那么它要么必须被忽略,要么必须被视为签名的一部分;通常,它被大多数编译器忽略) .

如果编译器决定内联,所有这些都变得无关紧要,因为根本没有真正的“参数传递”。

register 是强制执行的,因此它可以作为您不会使用该地址的断言;任何这样做的尝试都是编译错误。

关于c - __fastcall 与注册语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22247709/

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