main()的非标准签名成功编译

时间:2012-06-16 15:02:07

标签: c main

在此代码中:

int main(int a, int b)
{
    printf(" main(int, int) works \n\n");
    return 0;
}

main的签名是main(int, int)it compiles successfully。为什么呢?

4 个答案:

答案 0 :(得分:12)

因为C标准不禁止main的非标准签名(参见例如C99标准的第5.1.2节)。

但是,您会发现,如果您使用-Wall标志在GCC下编译, 1 ,它会抱怨:

test.c:4: warning: second argument of 'main' should be 'char **'

它假定您希望与标准环境交互(即处理命令行参数并返回退出状态),在这种情况下,您必须使用int main(int, char **)int main(void)。如果你使用其他任何东西,参数的内容将是未定义的。

<小时/> <子> 1。我真的希望ideone.com允许你指定编译器标志!

答案 1 :(得分:3)

C标准明确禁止实现为main提供原型(C99,§5.1.2.2.1/ 1:“程序启动时调用的函数名为main。实现声明没有这个函数的原型。“),与原型的不匹配是(通常)停止编译的代码。

如果没有原型,你就会像过去那样重新编程,当你需要确保传递给函数的参数与预期相符时。值得庆幸的是,在main的情况下,签名是众所周知的,但它很少是一个问题。

编辑:请注意,如果您想要足够严重,实际上甚至可以使用具有两个int参数的版本(尽管C ++中禁止使用该技术)。 main可以递归调用自身,在这种情况下可以/可以传递两个int参数:

int main(int a, int b) { 
     if (a == 2)
         main(2, 10);

     printf("%d, %d", a, b);
     return 0;
}

这是无用的,但它给出了一般的想法 - 你应该在没有命令行参数的情况下运行程序,在这种情况下a(它将接收你通常称之为{{ 1}})通常是argc(即,它试图传递的唯一参数是argv [0]中程序的名称)。在这种情况下,它会使用其他一些值来调用自身。当发生这种情况时,它会打印出这些值。

公平地说,我应该补充说,这非常接近纯理论,当然不推荐。它适用于大多数典型的实现,但标准并不能保证它。这是一种愚蠢,迂回的方式来完成它的工作 - 但至少对于大多数典型的编译器来说,无论如何都是(几乎不可能)。

答案 2 :(得分:1)

没有指定main签名的头文件,因此不会报告错误。对于main的情况,编译器通常仅检查返回值(main的签名警告依赖于编译器)。

答案 3 :(得分:1)

int main(int a, int b)

这是没有意义的,因为传递给main函数的参数总是

int main(int argc,char *argv[])

main是一个不寻常的函数。它由操作系统调用,并且由于C ++可以在许多系统上运行,并且C ++标准不能指示OS编写者将哪些数据传递给在该OS上运行的程序 - 您可以编写任何参数你喜欢主要功能,编译器会接受它。