我应该将参数存储类说明符放在函数定义中还是同时放在声明和定义中?

2023-12-31

我正在努力将一些旧的 K&R 代码移植到 ANSI C,因此我正在编写缺少的函数原型声明。很多函数定义的参数都带有寄存器存储类,但我不确定函数原型中是否可以省略寄存器存储类说明符?

无论有或没有寄存器存储类特定声明,代码都能正确编译(我尝试了 GCC、VC++ 和 Watcom C)。我在 ISO/ANSI C89 标准中找不到任何关于正确方法的信息 - 如果我只是将 register 关键字放在函数定义中可以吗?

int add(register int x, register int y); 

int add(register int x, register int y)
{
  return x+y;
}

这也可以正确构建:

int add(int x, int y);

int add(register int x, register int y)
{
   return x+y;
}

我想确保根据标准确实考虑了寄存器存储说明符(我的目标是使用非常旧的编译器进行编译,其中该存储类说明符很重要)。两者都可以吗?这只是编码风格的问题吗?


关键规定是函数的每个声明都必须为其指定兼容类型。这需要兼容的返回类型,并且对于像您这样包含参数列表的声明,每对相应参数的类型都需要兼容。

那么问题就变成存储类说明符是否区分类型。尽管标准通过在类型派生的讨论中省略存储类说明符间接说明了这一点,但它们并没有这样做。因此,对象声明中存储类说明符指定的属性与该对象的类型是分开的。

此外,C89具体说 http://port70.net/~nsz/c/c89/c89-draft.html#3.5.4.3

参数声明的声明说明符中的存储类说明符(如果存在)被忽略除非声明的参数是函数定义的参数类型列表的成员之一。

(强调已添加)。函数定义是伴随函数体的声明,而不是前向声明,因此两个代码具有相同的语义。

有或没有寄存器存储类特定声明, 代码编译正确(我尝试了 gcc、VC++ 和 Watcom),但我无法 在 ISO/ANSI C89 标准中查找有关什么是的任何信息 正确的方法,或者我只需将寄存器关键字放入即可 函数定义?

就我个人而言,我倾向于使每个前向声明与相应函数定义中的声明相同。如果函数定义本身是正确的,那么这永远不会错。

HOWEVER,

  1. The register关键字是一个遗迹。编译器没有义务进行任何实际分配的尝试register变量到寄存器,现代编译器在决定如何将变量分配到寄存器以及以其他方式生成快速代码方面比人类要好得多。只要您要转换旧代码,我就会趁机删除所有出现的register关键词。

  2. C89 已过时。该标准最新版本为C 2018; C 2011广泛部署; C99(从技术上来说,也已经过时了)几乎随处可见。也许您有充分的理由以 C89 为目标,但您应该强烈考虑以 C11 或 C18 为目标,或者at least C99.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该将参数存储类说明符放在函数定义中还是同时放在声明和定义中? 的相关文章

随机推荐