这个函数定义是如何工作的?

问题描述 投票:0回答:3

几天前我用

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

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

现在,当我尝试使用 C++ 编译器 (g++) 进行编译时,它会因为没有声明

str
size
而向我抛出错误。但这是在 C 编译器(gcc)上编译的。所以,问题:

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

1.  C++ 不是超集,尽管它也不是标准 C。

2/3。这是一个 K&R 函数声明。 请参阅ANSI C 和 K&R C 之间的主要区别是什么? .

4. gperf 实际上有一个选项

-L
来指定语言。 您只需使用
-L C++
即可使用 C++。


2
投票

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

例如

int func (x) 
int x 
{

}

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

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

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


2
投票

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

回答您的问题:

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

  2. 大多数当代 C 编译器都可以理解遗留代码(就像看起来的那样)。 C 编译器保留类似于“占位符”的函数参数名称,直到可以在函数头名称之后立即声明它们的类型。

  3. 除了再次之外没有真正的“目的”,这似乎是古老的代码,当时的风格就是这样。 在我看来,“正常”方法是更好、更直观的方法。

  4. 我的建议:

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

建议:考虑放弃

register
关键字 - 这在旧的 C 程序中用作指定变量将存储在内存寄存器中的方式(为了速度/效率),但现在编译器更擅长优化消除这种需要。 我相信现代编译器会忽略它。 此外,您不能在 C/C++ 中对
&
变量使用
register
(地址)运算符。

© www.soinside.com 2019 - 2024. All rights reserved.