代码之家  ›  专栏  ›  技术社区  ›  RobertS supports Monica Cellio

我应该在现代C程序中使用寄存器类变量吗?

  •  1
  • RobertS supports Monica Cellio  · 技术社区  · 6 年前

    在C++中,关键字 register 在其最新标准ISO/IEC 14882:2017(C++17)中删除。

    但在C语言中,我也看到了很多,越来越多的程序员倾向于不使用或喜欢使用 登记 类限定符,因为它的目的是几乎无用的,比如 @user253751´s answer :

    登记 不会导致编译器在寄存器中存储值。 登记 什么都不做。只使用非常旧的编译器 登记 知道哪些变量要存储在寄存器中。新的编译器会自动完成这项工作。即使是20岁的编译器也会自动完成这项工作。

    • 是使用 登记 类变量,并使用关键字 登记 不赞成?

    • 我要用吗 登记 我的现代程序中的类变量?或者这种行为是多余的,不受欢迎的?

    1 回复  |  直到 6 年前
        1
  •  5
  •   Jonathan Leffler    6 年前

    使用它没有好处 register .现代编译器基本上忽略了这一点——它们可以比您更好地处理寄存器分配。它唯一能阻止的就是获取变量的地址,这并不是一个显著的好处。

    我自己的代码都不使用 登记 再。我编写的代码丢失了 登记 当我开始处理一个文件,但需要花费时间来处理17000多个文件时(只有当我有外部原因要更改一个文件时,我才会更改它,但这可能是一个不可靠的原因)。

        2
  •  3
  •   0___________    6 年前

    正如@JonathanLeffler所说,它在大多数情况下被忽略。

    如果要将变量保留在特定寄存器中,某些编译器有一种特殊的扩展语法。

    gcc 全局或局部变量可以放在特定寄存器中。此选项不适用于所有平台。我知道AVR&ARM端口实现了它。

    例子:

    register int x asm ("10");
    
    int foo(int y)
    {
        x = bar(x);
        x = bar1(x);
        return x*x;
    }
    

    https://godbolt.org/z/qwAZ8x

    更多信息: https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Explicit-Register-Variables.html#Explicit-Register-Variables

    但说实话,在我的编程生涯中(30岁以上),我从未使用过它

        3
  •  1
  •   John Bode    6 年前

    它实际上已经被弃用了,而且没有真正的好处。

    C是20世纪70年代早期的产物 register 关键字向编译器提示a)这个特定的对象将被大量使用,因此b)您可能希望将其存储在主内存以外的其他位置——IOW、寄存器或其他一些“快速”内存。

    信息技术 也许 在当时已经产生了影响——现在,它几乎被忽视了。唯一可测量的影响是,它阻止您获取该对象的地址。

        4
  •  1
  •   emacs drives me nuts    6 年前

    首先,这个特性没有被弃用,因为在这个上下文(全局或局部寄存器变量)中的“register”是一个GNU扩展,它没有被弃用。

    在您的示例中,R10(或GCC内部分配给REGNO(reg)=10的寄存器)是一个全局寄存器。这里的“全球”意思是 全部的 应用程序中的代码必须同意这种用法。对于libc、libm或libgcc等库中的代码,情况通常不是这样,因为它们不是用-ffix-10编译的。此外,全局寄存器可能与ABI冲突。例如,avr gcc可能会在R10中传递值。在avr gcc中,R2。。。ABI不使用R9,libgcc的代码也不使用R9(64位双精度除外)。

    在一些带有avr gcc的硬实时应用程序中,我使用了全局regs进行(过早)优化,只是为了注意到性能增益微乎其微。

    然而,本地寄存器变量在集成非ABI函数时非常方便,例如不符合GCC ABI的汇编函数,而不需要汇编包装器。