这个声明来自哪里:main _2a((argc,argv),int argc,char * argv [])

时间:2014-11-18 15:33:16

标签: c oracle-pro-c

我正在将HP-Unix下的大量Oracle Pro * C代码迁移到Linux环境。

在程序中只定义了这样一个主要方法:

main _2a((argc,argv), int argc, char * argv[])
{
...
}

我之前从未见过这样的诽谤 - 并且没有找到谷歌的任何东西。 无论如何,它起作用,从我看到的用作主要功能。

有人可以说出这个吗?

编辑: 好提示 - 有一个宏定义:

 # define _2a(list,a1,a2)                 list a1;a2;

仍然没有明确的观点(对我来说......)

2 个答案:

答案 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编译器在默认模式下仍然允许省略返回类型,可能带有警告,但没有充分的理由可以省略它。