"指向寄存器变量"作为函数参数吗?

时间:2018-06-01 07:31:15

标签: c function calling-convention function-declaration register-keyword

据我所知,register说明符提示编译器将变量存储在寄存器中。这一切都很好,直到我在Xorg-7.7的XKBlib.h中看到以下声明:

extern  int     XkbTranslateKeySym(
    Display *           /* dpy */,
    register KeySym *       /* sym_return */,
    unsigned int        /* modifiers */,
    char *          /* buffer */,
    int             /* nbytes */,
    int *           /* extra_rtrn */
);

注意sym_return如何作为指针传递给寄存器变量。是什么让我想知道是

  1. 这似乎是允许的,尽管无法获取寄存器变量的地址,
  2. 这在某种程度上似乎很重要,可以在函数声明中提及。
  3. 第1点似乎在某种程度上无效,因为我似乎能够将指针传递给非register变量,即使GCC为-pedantic-errors标志也是如此。

    那么,与省略register关键字的声明相比,此声明有何变化?它会改变调用约定还是什么?

2 个答案:

答案 0 :(得分:7)

register关键字在现代C中主要是一个过时的功能。它做了两件事:

  • 告诉编译器如果可能的话,它应该尝试将变量存储在CPU寄存器中。现在,编译器比程序员更适合进行此类调用,因此过时的功能。
  • 阻止程序员获取变量的地址。

在您的情况下,它表示指针本身,而不是指向的数据,应该优选地存储在寄存器中,可能是地址/索引寄存器。从标准的C视图来看,除此之外别无其他。

某个奇特的编译器可能会在给定register作为函数的一部分时选择某个调用约定,尽管我以前从未见过它。用于调用约定的Praxis更像是:"如果参数n是指针,则将其存储在索引寄存器x中,如果参数n + 1是指针,则将其存储为索引寄存器y"等等。

我怀疑这里register关键字最可能的解释是程序员不知道他们在做什么。特别是因为没有关于它的评论留在标题中 - 这是一个相当确定的无能的迹象。纵观整个标题,还有许多支持无能论的其他标志,例如这个明显的错误:#define XkbLC_BeepOnComposeFail (1<<31)。如果你能在短短几分钟内找到UB来简要查看来源,那就明白了。

答案 1 :(得分:1)

这不是寄存器变量的地址,即它不是寄存器变量的指针。相反,它暗示指针本身(记住,指针只是变量)应放在寄存器中。