我正在将HP-Unix下的大量Oracle Pro * C代码迁移到Linux环境。
在程序中只定义了这样一个主要方法:
main _2a((argc,argv), int argc, char * argv[])
{
...
}
我之前从未见过这样的诽谤 - 并且没有找到谷歌的任何东西。 无论如何,它起作用,从我看到的用作主要功能。
有人可以说出这个吗?
编辑: 好提示 - 有一个宏定义:
# define _2a(list,a1,a2) list a1;a2;
仍然没有明确的观点(对我来说......)
答案 0 :(得分:8)
此宏用于使K&R C - 样式函数定义看起来更像" modern" C89定义。
扩展代码:
main (argc,argv) int argc;char * argv[];
{
...
}
或者有更好的缩进:
main(argc, argv)
int argc;
char *argv[];
{
...
}
这是一种古老的写作方式:
int main(int argc, char *argv[])
{
...
}
答案 1 :(得分:6)
我们只需要扩展宏。您可以使用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”可能代表“参数”)允许您编写可以将 扩展为旧式函数定义的代码(用于ANSI之前的版本)编译器)或带有原型的现代定义。
实施它的合理方法是:
#ifdef __STDC__
#define _2a(list,a1,a2) (a1, a2)
#else
#define _2a(list,a1,a2) list a1;a2;
#endif
但是,由于你不太可能找到一个不支持原型的C编译器(它们已经成为该语言的标准功能,现在已有四分之一个世纪了),因此删除它会更有意义。完全宏,只使用现代风格的函数声明和定义。
此外,main
的定义缺少int
的返回类型。在1999 C标准之前,在“隐式int
”规则下省略返回类型是合法的。 1999标准删除了这条规则并强制要求显式返回类型。大多数C编译器在默认模式下仍然允许省略返回类型,可能带有警告,但没有充分的理由可以省略它。