我应该将参数存储类说明符放在函数定义中还是放在声明和定义中? [英] Should I place the parameter storage class specifier in the function definition or in both the declaration and definition?
问题描述
我正在努力将一些旧的K& R代码移植到ANSI C,所以我正在编写缺少的函数原型声明.许多函数定义都有寄存器存储类的参数,但是我不确定是否可以在函数原型中省略寄存器存储类说明符?
I'm working on porting some old K&R code to ANSI C, so I'm writing missing function prototype declarations. A lot of the function definitions have parameters with the register storage class, but I'm not sure if the register storage class specifier can be omitted in the function prototype?
使用和不使用特定于寄存器存储类的声明,代码均可正确编译(我尝试使用GCC,VC ++和Watcom C).我在ISO/ANSI C89标准中找不到关于正确方法的任何信息-如果只将register关键字放入函数定义中就可以了吗?
With and without the register storage class specific declaration, the code compiles correctly (I tried GCC, VC++ and Watcom C). I could not find any information in the ISO/ANSI C89 standard on what is the correct way to do - is it OK if I just put the register keyword in the function definition?
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;
}
根据标准,我想确保确实考虑了寄存器存储说明符(我的目标是使用非常老的编译器进行编译,而该存储类说明符很重要).都可以,这只是编码风格的问题吗?
I want to make sure that the register storage specifier is really taken into account, according to the standard (my target is to compile using a very old compiler where this storage class specifier is important). Are both OK and it's just a question of coding style, or not?
推荐答案
关键规定是,函数的每个声明都必须为其指定兼容的类型.这需要兼容的返回类型,对于诸如包含参数列表的声明,需要每对对应参数的兼容类型.
The key provision is that every declaration of the function must specify a compatible type for it. That requires compatible return types, and, for declarations such as yours that contain parameter lists, compatible type for each pair of corresponding parameters.
然后,问题就变成了存储类说明符是否区分类型.尽管该标准间接说明了这一点,但它们并不是通过忽略对类型派生的讨论而忽略存储类说明符来实现的.因此,由对象的声明中的存储类说明符指定的属性与该对象的类型是分开的.
The question then becomes whether storage-class specifiers differentiate types. They do not, though the standard says that indirectly, by omission of storage-class specifiers from its discussion of type derivation. The property specified by a storage-class specifier in an object's declaration is therefore separate from that object's type.
此外,C89 专门说
除非存在声明的参数是函数定义的参数类型列表的成员之一,否则参数声明的声明说明符中的存储类说明符(如果存在)将被忽略.
(添加了强调).函数定义是伴随函数体的声明,而不是向前声明,因此您的两个代码具有相同的语义.
(emphasis added). A function definition is a declaration accompanied by a function body, as opposed to a forward declaration, so your two codes have identical semantics.
在有和没有寄存器存储类特定声明的情况下,代码正确编译(我尝试过gcc,VC ++和Watcom),但我无法在ISO/ANSI C89标准中找到有关什么的任何信息正确的方法,还是可以,如果我只是将register关键字放入函数定义?
With and without the register storage class specific declaration, the code compiles correctly (I tried gcc, VC++ and Watcom), I could not find any information in the ISO/ANSI C89 standard on what is the correct way to do, or is it ok if i just put the register keyword in the function definition?
就个人而言,我倾向于使每个前向声明与相应函数定义中的声明相同.如果函数定义本身正确,就永远不会出错.
Personally, I would be inclined to make each forward declaration identical to the declaration in the corresponding function definition. This is never wrong if the function definition itself is correct.
但是,
-
register
关键字是一个遗物.编译器完全没有义务尝试将register
变量真正分配给寄存器,而现代编译器在决定如何将变量分配给寄存器以及无论如何生成快速代码方面比人类要好得多.只要您要转换旧代码,我就会借此机会删除register
关键字的所有外观.
The
register
keyword is a relic. Compilers are not obligated to make any attempt at all to actually assignregister
variables to registers, and modern compilers are a lot better than humans at deciding how to assign variables to registers and otherwise to generate fast code anyway. As long as you're converting old code, I would take the opportunity to remove all appearances of theregister
keyword.
C89已过时.该标准的最新版本为C 2018;C 2011已广泛部署;C99(从技术上讲也是过时的)几乎在任何地方都可以买到.也许有充分的理由将您定位到C89,但您应该强烈考虑改为定位C11或C18,或者至少定位 C99.
C89 is obsolete. The latest version of the standard is C 2018; C 2011 is widely deployed; and C99 (also, technically, obsolete) is available almost everywhere. Perhaps there is a good reason for you to target C89, but you should strongly consider instead targeting C11 or C18, or at least C99.
这篇关于我应该将参数存储类说明符放在函数定义中还是放在声明和定义中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!