我在Linux上用GCC(gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04.3))运行了这个程序。它使用gcc myprog.c
成功编译并在没有任何警告或错误的情况下运行。
那么,为什么在C中只为main
提供一个参数时,编译器是否会给出任何警告或错误?
#include <stdio.h>
int main(int i)
{
printf("%d\n", i);
}
答案 0 :(得分:5)
使用GCC 6(在Linux / Debian / Sid / x86-64上),我的编译器在使用gcc -Wall rsp.c -o rsp
rsp.c
示例进行编译时会发出一些警告。
rsp.c:3:5: warning: ‘main’ takes only zero or two arguments [-Wmain]
int main(int i)
^~~~
但是C11编程语言(read n1570)没有指定编译器何时应该发出警告。它主要定义了什么是正确的可能的程序以及它们应该如何表现。阅读更多关于undefined behavior的信息(我猜,但我不确定,你有一个)。
如果您想真正了解计算机中实际发生的情况,请研究编译器的源代码,发出的汇编程序代码(使用gcc -S -fverbose-asm -O rsp.c
编译,然后查看生成的rsp.s
),C standard library运行时crt0的源代码。还要研究与您的系统相关的ABI和calling conventions。
我认为你应该非常害怕未定义的行为。非常bad things could happen。
作为在Linux上编码时的实用建议,始终使用-Wall
进行编译,并将-g
传递给gcc
-Wall
选项会询问几乎所有警告(您可以添加-Wextra
)。 -g
选项要求提供调试信息。然后,您将能够使用gdb
调试器来了解运行时发生的更多信息。
一旦您对代码充满信心并对其进行了调试,请考虑使用-O
或-O2
进行编译,以请求optimization(特别是对于基准测试)。 (顺便说一句,gcc
可以同时接受-g
和-O2
)。阅读GCC command options上的文档。
答案 1 :(得分:4)
根据C标准
程序启动时调用的函数名为main。该实现声明此函数没有原型。它应定义为返回类型
int
且没有参数:int main(void) { /* ... */ }
或有两个参数(此处称为
argc
和argv
,但可以使用任何名称,因为它们是声明它们的函数的本地名称):int main(int argc, char *argv[]) { /* ... */ }
或同等的; 或以其他一些实现定义的方式。
如果实现将其定义为接受单个参数,则可以。