这个函数定义如何工作?

时间:2010-11-21 04:06:20

标签: c++ c compiler-construction syntax

我几天前用gperf生成了一个哈希函数。我所看到的hash函数对我来说是陌生的。它是这样的(我不记得确切的语法):

unsigned int
hash(str, size)
   register char* str;
   register unsigned int size;
{
   //Definition
}

现在,当我尝试使用C ++编译器(g ++)进行编译时,由于未声明strsize,因此向我提出错误。但这是在C编译器(gcc)上编译的。所以,问题:

  1. 我认为C ++是C的超集。如果是这样的话,这应该用C ++编译器编译吗?
  2. C编译器如何理解定义? strsize首次出现时未声明。
  3. 在函数签名之后但在函数体之前声明strsize而不是遵循在两个地方中的任何一个地方执行它的正常方法的目的是什么?
  4. 如何让这个函数在g ++上编译,以便我可以在我的C ++代码中使用它?或者我应该尝试从gperf生成C ++代码?那可能吗?

3 个答案:

答案 0 :(得分:10)

1。 C ++不是超集,虽然这也不是标准C。

2/3。这是K& R函数声明。请参阅What are the major differences between ANSI C and K&R C?

4。实际上,gperf确实有一个选项-L来指定语言。您可以使用-L C++来使用C ++。

答案 1 :(得分:2)

一些编译器仍然支持声明函数正式参数的旧C语法。

例如

int func (x) 
int x 
{

}

是用于定义函数的旧样式(K& R样式)语法。

  

我认为C ++是C的超集。如果是这样的话,这应该用C ++编译器编译吧?

Nopes! C ++不是C的超集。函数声明/定义的这种风格(语法)曾经是C的一部分,但从未成为C ++的一部分。所以它不应该用C ++编译器编译。

答案 2 :(得分:2)

这似乎是“老派”C代码。声明括号外的参数类型,但在代码块的开放式卷曲括号之前是C编程早期的遗留物(我不知道为什么,但我猜它与变量管理有关)堆栈和/或编译器设计)。

回答你的问题:

  1. 将C ++称为C的“超集”有点用词不当。虽然它们共享基本的语法功能,您甚至可以使用C ++进行各种C库调用,但它们在类型安全性,警告与错误(C更允许)以及编译器/预处理器选项方面存在显着差异。

  2. 大多数现代C编译器都了解遗留代码(例如这似乎是)。 C编译器保存函数参数名称,类似于“占位符”,直到它们的类型可以紧跟函数头名称后声明。

  3. 除了再一次没有真正的“目的”,这似乎是古老的代码,当天的风格就像这样。 “正常”方法是IMO更好,更直观的方式。

  4. 我的建议:

    unsigned int hash(register char * str,register unsigned int size) {     //定义 }

  5. 建议:考虑放弃register关键字 - 这在旧C程序中用作指定变量将存储在内存寄存器中的方式(为了速度/效率),但现在编译器更好地优化这种需求。我相信现代编译器会忽略它。此外,您不能在&变量上使用C / C ++中的register(地址)运算符。