我们只需要扩展宏。您可以使用gcc -E
仅调用预处理器;它还将扩展所有#include
指令,因此输出会很丑陋。
但是让我们手动完成。宏的参数是标记序列,而不是表达式。
宏定义为:
# define _2a(list,a1,a2) list a1;a2;
调用是:
main _2a((argc,argv), int argc, char * argv[])
{
...
}
论据是:
list
-->(argc,argv)
a1
-->int argc
a2
-->char * argv[]
执行替换给我们:
main (argc,argv) int argc; char * argv[];
{
...
}
这通常会写在多行上:
main(argc, argv)
int argc;
char *argv[];
{
...
}
这是一个老式的函数声明。它在所有 C 版本(直到并包括 2011 标准)中仍然是合法的,但自 1989 年以来它已正式过时。这种旧形式的缺点是它不会将参数信息传达给调用者,因此编译器不能如果您使用错误数量的参数类型调用函数,则会警告您。
我敢打赌,_a2
宏的替代定义会扩展为包含原型的更现代的定义,例如:
#define _2a(list,a1,a2) (a1, a2)
使用该宏定义, 的定义main
改为扩展为:
main (int argc, char * argv[])
{
...
}
因此,_a2
宏(“a”可能代表“argument”)让您编写的代码既可以扩展为旧式函数定义(用于 ANSI 前编译器),也可以扩展为带有原型的现代定义。
实现它的合理方法是:
#ifdef __STDC__
#define _2a(list,a1,a2) (a1, a2)
#else
#define _2a(list,a1,a2) list a1;a2;
#endif
但是由于您不太可能找到不支持原型的 C 编译器(它们已经成为该语言的标准特性已有 25 年了),因此完全删除宏和只需使用现代风格的函数声明和定义。
此外, 的定义main
缺少 的返回类型int
。在 1999 C 标准之前,根据“隐式int
”规则,省略返回类型是合法的。1999 年的标准删除了这条规则,并强制要求明确的返回类型。大多数 C 编译器在其默认模式下仍然允许省略返回类型,可能带有警告,但没有充分的理由省略它。