为什么在将main声明为`int main(void)`时传递命令行参数时没有错误?

时间:2015-10-24 10:37:06

标签: c command-line-arguments main

案例1:

void hello(void) {
    //something
}

int main()
{
    hello(1); //error
    return 0;
}

案例2:

int main(void) {
    //something
    return 0;
}

执行:

./a.out something something //No error, Why?

为什么没有错误? main将无法接受任何争论。那么为什么可以从命令行提供参数呢?

5 个答案:

答案 0 :(得分:14)

因为C编译器和命令行解释器(或用于调用程序的任何东西)是不同的东西。

C语言允许以各种方式声明main()。

命令行解释器将使程序可以使用任何参数。如果程序忽略它们,那就不是它的业务。

命令行解释器甚至不知道您使用C编译程序。在我的计算机上,程序可以用C,C ++,Objective-C,Objective-C ++,Swift,Fortran,Ada等编写。这些编译器中的每一个都可能会或可能不会从命令行接受命令。

答案 1 :(得分:9)

不检查规范或编译结果,它不会导致错误,因为C运行时将获取参数并将它们传递给main(),但是这种类型的main()将忽略传递的参数,并且如果调用者有责任清理用作参数的内存(堆栈),那么就不会产生任何问题,就像获取一些参数而不在代码中使用它们一样。

此代码不会在C:

中发出错误
void hello(); // in C, the compiler won't check arguments

int main() {
    hello(1); //no error
    return 0;
}

void hello(void) {
    //something 
}

答案 2 :(得分:5)

因为./a.out something something没有直接调用您的主函数。主要功能由c运行时库调用。命令行参数由loader / c运行时放置在堆栈中的某个区域(最开始)。如果您想要访问这些参数,则由您决定。

正如其中一条评论所指出的那样,至少有一个命令行参数始终是传递的(程序的名称./a.out是准确的) - 所以你一定想知道一个错误案件也是如此。

答案 3 :(得分:3)

回想一下,ISO C指定mainint main(void)int main(int, char *[])及其等效版本的两个可能签名,如int main(int, char **)因为数组到指针的衰减。详细介绍here

可以通过考虑相反的问题来回答这个问题: C运行时如何知道要调用的main ? C没有重载决议!这是here的解释。简而言之,其他人被推,但没有被访问,因为C没有迹象表明这样做。

答案 4 :(得分:2)

使用gcc program_name.c编译程序时,编译器将报告任何可能的编译时警告或错误。由于命令行参数在编译时没有传递,编译器不知道它,程序只是忽略那些参数。

hello的情况下,编译器知道该函数的原型,并且期望在其调用中不传递参数,因此在传递任何参数的情况下报告错误。