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

Ste*_*fan 6 c oracle-pro-c

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

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

main _2a((argc,argv), int argc, char * argv[])
{
...
}
Run Code Online (Sandbox Code Playgroud)

我以前从未见过这样的装饰 - 并且没有找到谷歌的任何东西.无论如何,它的工作原理和我所看到的用作主要功能.

任何人都能说出这个吗?

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

 # define _2a(list,a1,a2)                 list a1;a2;
Run Code Online (Sandbox Code Playgroud)

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

kay*_*kay 8

该宏用于使K&R C风格的函数定义看起来更像"现代"C89定义.

扩展代码如下:

main (argc,argv) int argc;char * argv[];
{
...
}
Run Code Online (Sandbox Code Playgroud)

或者有更好的缩进:

main(argc, argv)
    int argc;
    char *argv[];
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是一种古老的写作方式:

int main(int argc, char *argv[])
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • 我只是想通过多年CRT监测辐射照射所获得的力量来帮助人类.;) (3认同)
  • 我只想指出它与*int main(int argc,char*argv [])`相当*.后者导致参数被隐式转换(如果它们是隐式可转换类型)或者如果它们不是预期类型则被诊断出来; 使用非原型定义/声明,带有错误参数的调用具有未定义的行为.另外,省略返回类型并将其默认为"int"是合法的,包括C89/C90/C95,但从来都不是一个特别好的主意. (2认同)

Kei*_*son 7

我们只需要扩展宏.您可以使用gcc -E仅调用预处理器; 它还将扩展所有#include指令,因此输出将是丑陋的.

但是,让我们手动完成.宏的参数是令牌序列,而不是表达式.

宏定义是:

# define _2a(list,a1,a2)                 list a1;a2;
Run Code Online (Sandbox Code Playgroud)

并且调用是:

main _2a((argc,argv), int argc, char * argv[])
{
...
}
Run Code Online (Sandbox Code Playgroud)

论点是:

  • list - > (argc,argv)
  • a1 - > int argc
  • a2 - > char * argv[]

执行替换为我们提供:

main (argc,argv) int argc; char * argv[];
{
...
}
Run Code Online (Sandbox Code Playgroud)

这通常会写在多行上:

main(argc, argv)
int argc;
char *argv[];
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是一个旧式的函数声明.它仍然在C(直至并包括2011年标准)的所有版本合法的,但它已经过时的官方自1989年以来的这个古老形式的缺点是,它没有传达参数信息呼叫者,所以编译器不能如果您使用错误数量的参数调用函数,则会发出警告.

我敢打赌,有一个_a2宏的替代定义,扩展到更现代的定义,包括原型,如:

#define _2a(list,a1,a2) (a1, a2)
Run Code Online (Sandbox Code Playgroud)

使用该宏定义,main相反的定义扩展为:

main (int argc, char * argv[])
{
...
}
Run Code Online (Sandbox Code Playgroud)

所以_a2宏("一"大概是代表"参数"),可以让你写的代码,可以扩大或者以旧风格函数定义(预ANSI编译器)或到现代定义与原型.

实现它的合理方法是:

#ifdef __STDC__
#define _2a(list,a1,a2) (a1, a2) 
#else
#define _2a(list,a1,a2) list a1;a2;
#endif
Run Code Online (Sandbox Code Playgroud)

但是,由于你不太可能找到一个不支持原型的C编译器(它们已经成为该语言的标准功能,现在已经有四分之一个世纪了),所以只需完全删除宏就更有意义了.只需使用现代风格的函数声明和定义.

另外,定义main缺少返回类型int.在1999 C标准之前,在"隐含int"规则下省略返回类型是合法的.1999标准删除了这条规则并强制要求显式返回类型.大多数C编译器在其默认模式下仍然允许省略返回类型,可能带有警告,但没有充分的理由省略它.