4

我无法计算我在那里和这里看到 C 代码的次数,将main定义为

int main() { ...

当我编译它时

gcc -ansi -pedantic -Wstrict-prototypes -Werror foo.c

它出错了

foo.c:2: warning: function declaration isn't a prototype

为什么会这样

int main(void)

需要使错误消失吗?

4

3 回答 3

8

因为定义

int main() { /* ... */ }

不包括原型;它没有指定参数的数量或类型。

这:

int main(void) { /* ... */ }

确实包括一个原型。

使用空括号,您是说它main采用固定但未指定数量和类型的参数。使用(void),您明确表示它不需要任何参数。

对于前者,调用如下:

main(42);

不一定会被诊断出来。

这可以追溯到原型被引入语言之前的 ANSI 之前的日子,大多数函数都是用空括号定义的。那时,这样写是完全合法的:

int foo();

int foo(n)
int n;
{
    /* ... */
}

...

foo(42);

当原型被添加到语言中时(从 C++ 中借用),有必要保留空括号的旧含义;添加了“新”(这是 1989 年)语法(void),因此您可以明确地说函数不带参数。

(C++ 有不同的规则;它不允许老式的非原型函数,空括号意味着函数不带参数。C++ 允许(void)与 C 兼容的语法,但通常不推荐。)

最佳实践是使用(void),因为它更明确。表单是否有效还不完全清楚int main(),但我从未见过不接受它的编译器。

于 2013-04-03T19:24:55.043 回答
2

它不会出错 - 它会发出警告。该标志说明了一切:它希望您关心main(通常是int argc, char **argv).

于 2013-04-03T19:22:45.323 回答
1

根据gcc 文档,添加时会发出警告,-Wstrict-prototypes因为:

-Wstrict-prototypes(仅限 C 和 Objective-C)
如果在声明或定义函数时未指定参数类型,则发出警告。(如果前面有一个指定参数类型的声明,则允许在没有警告的情况下进行旧式函数定义。)

但对你来说这是一个错误,因为-Werror

-Werror
将所有警告变成错误。

一般来说,定义一个main()类似的东西是错误的(不管你在这里看到了什么),C 规范定义了main()5.1.2.2.1 中的外观:

程序启动时调用的函数名为 main。实现没有声明这个函数的原型。它应定义为返回类型为 int 且不带参数:

int main(void) { /* ... */ }

或者带有两个参数(这里称为 argc 和 argv,尽管可以使用任何名称,因为它们是声明它们的函数的局部变量):

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

于 2013-04-03T19:36:54.430 回答