我有一个包含的头文件
#define PROTOTYPE(s) s
这有什么意义?似乎只是将输入替换为自身。
围绕它还有其他大量指令,但是唯一一个似乎与指令无关的指令(如果已定义):#ifndef PROTOTYPE
。我在HDF4头文件中找到了执行此操作的位置:#define PROTOTYPE
。因此,这些都不能真正解决我的问题。似乎还是没用。
使用方法如下:
CS_RETCODE clientmsg_callback PROTOTYPE((
CS_CONTEXT * context,
CS_CONNECTION *connection,
CS_CLIENTMSG *clientmsg));
这是使用Sybase Open Client的项目的一部分。稍后在此处使用clientmsg_callback:
ct_callback(context, NULL, CS_SET, CS_CLIENTMSG_CB,
(CS_VOID *)clientmsg_callback);
我要从这里开始一个示例程序:
clientmsg_callback稍后实现。我认为该示例最初是考虑到C而不是C ++编写的。也许与它有关?
答案 0 :(得分:129)
在真正非常早期的C时代,还没有原型。函数参数列表位于函数括号like this之后:
square(x)
int x;
{
int y = x * x;
return y;
}
这些天,当然,参数放在括号内:
square(int x)
{
int y = x * x;
return y;
}
请注意“缺少”返回类型; C函数曾经隐式返回int
,只有在您需要其他返回类型时,才必须说出它是什么。
函数声明还有另一套规则。 K&R C(古代版本)中的函数声明没有参数:
int square();
ANSI C中的函数原型具有参数列表:
int square(int x);
在过渡期间,人们使用了古怪的宏,因此可以用两种方式进行编译:
int square(PROTOTYPE(int x));
使用
#define PROTOTYPE(s)
将会扩展到第一个版本。
使用
#define PROTOTYPE(s) s
它将扩展到第二个。
关于问题代码中的“额外”括号,当参数列表中有多个参数时,需要使用它们。没有它们,宏调用将具有多个参数,因此不会与仅具有一个参数定义的宏匹配:
PROTOTYPE(int x, int y) // error: too many arguments
PROTOTYPE((int x, int y)) // ok: only one argument (enclosed in parentheses)
答案 1 :(得分:15)
在头文件的原型中将使用类似这样的宏,以允许这样的事情:
int foo PROTOTYPE((int bar));
如果检测到ANSI C(__STDC__
定义为1),它将扩展为:
int foo(int bar);
如果未检测到ANSI C,它将扩展为:
int foo();
在C标准化之前很常见。
某些图书馆仍然这样做;如果您查看tcpd.h
(如果有),则会看到:
/* someone else may have defined this */
#undef __P
/* use prototypes if we have an ANSI C compiler or are using C++ */
#if defined(__STDC__) || defined(__cplusplus)
#define __P(args) args
#else
#define __P(args) ()
#endif
这很好解释。
对于双括号,__P(arg1, arg2)
会产生语法错误(将太多的参数传递给宏),而__P((arg1, arg2))
会很好(仅括在括号中)。
这类似于GNU C中的__extension__((...))
。在非GNU编译器中,只需#define __extension__(unused)
具有半便携式代码,只需给出一个“参数”,并用括号括起来即可。