仅扩展为其参数的PROTOTYPE宏有什么意义?

Cha*_*son 80 c++ macros

我有一个头文件,其中包含

#define PROTOTYPE(s) s
Run Code Online (Sandbox Code Playgroud)

这有什么意义呢?似乎它将只是用自身替换输入。

还有它周围的其他指令吨,但似乎有如果它被定义任何影响只是检查只有一个:#ifndef PROTOTYPE。我在HDF4头文件中找到了执行以下操作的位置:#define PROTOTYPE。因此,这些都不能真正解决我的问题。似乎还是没用的。

使用方法如下:

CS_RETCODE clientmsg_callback PROTOTYPE((
CS_CONTEXT * context,
CS_CONNECTION *connection,
CS_CLIENTMSG *clientmsg));
Run Code Online (Sandbox Code Playgroud)

这是使用Sybase Open Client的项目的一部分。稍后在此处使用clientmsg_callback:

ct_callback(context, NULL, CS_SET, CS_CLIENTMSG_CB,
                  (CS_VOID *)clientmsg_callback);
Run Code Online (Sandbox Code Playgroud)

我将从这里开始一个示例程序:

http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc35570.1570/html/clcprgde/clcprgde10.htm

clientmsg_callback稍后实现。我认为该示例最初是考虑到C而不是C ++编写的。也许与它有关?

Pet*_*ker 128

早在C语言的真正早期,就没有原型这样的东西。函数参数列表位于函数的括号之后,如下所示

square(x)
int x;
{
int y = x * x;
return y;
}
Run Code Online (Sandbox Code Playgroud)

这些天,当然,参数放在括号内:

square(int x)
{
int y = x * x;
return y;
}
Run Code Online (Sandbox Code Playgroud)

注意“ missing”返回类型;C函数曾经隐式地返回int,并且只有在您需要其他返回类型时,才必须说出它是什么。

函数声明还有另一套规则。K&R C(较旧的版本)中的函数声明没有参数:

int square();
Run Code Online (Sandbox Code Playgroud)

ANSI C中的函数原型具有参数列表:

int square(int x);
Run Code Online (Sandbox Code Playgroud)

在过渡期间,人们使用了古怪的宏,因此他们可以两种方式进行编译:

int square(PROTOTYPE(int x));
Run Code Online (Sandbox Code Playgroud)

#define PROTOTYPE(s)
Run Code Online (Sandbox Code Playgroud)

它将扩展到第一个版本。

#define PROTOTYPE(s) s
Run Code Online (Sandbox Code Playgroud)

它将扩展到第二个。

关于问题代码中的“额外”括号,当参数列表中有多个参数时,需要使用它们。没有它们,宏调用将具有多个参数,因此不会与仅具有一个参数定义的宏匹配:

PROTOTYPE(int x, int y)   // error: too many arguments
PROTOTYPE((int x, int y)) // ok: only one argument (enclosed in parentheses)
Run Code Online (Sandbox Code Playgroud)

  • 我不明白这些定义是如何工作的,带有输入“ int x;”的“ #define PROTOTYPE(s)”如何变成“ x”?看起来好像对我来说是一个空字符串 (15认同)
  • 哇。过去的冲击波。我从事软件的第一批工作之一就是将这些东西从现有的代码库中剥离出来。对Unix的单行文本更改程序数组建立了健康的尊重。 (10认同)
  • @Ferrybig-对不起,我很困惑。原型就是这样定义的。在K&R C中,原型没有参数,而在ANSI C中,它具有我们常用的参数列表样式。 (3认同)

JL2*_*210 15

此类宏将用于头文件的原型中,以允许类似以下内容:

int foo PROTOTYPE((int bar));
Run Code Online (Sandbox Code Playgroud)

如果检测到ANSI C(__STDC__定义为1),它将扩展为:

int foo(int bar);
Run Code Online (Sandbox Code Playgroud)

如果未检测到ANSI C,它将扩展为:

int foo();
Run Code Online (Sandbox Code Playgroud)

这在C标准化之前很常见。

一些图书馆仍然这样做。如果您浏览tcpd.h(如果有),将会看到:

int foo PROTOTYPE((int bar));
Run Code Online (Sandbox Code Playgroud)

这很好地解释了。

至于双括号,__P(arg1, arg2)将给出语法错误(将太多的参数传递给宏),而__P((arg1, arg2))将是很好的(仅括在括号中)。

这类似于__extension__((...))GNUC。在非GNU编译器中,仅#define __extension__(unused)提供半便携式代码,因为仅给出了一个“参数”,并用括号括起来。