为什么 "int main(anything_you_type)" 不会产生任何错误?

9

尽管在主参数声明中写了我的名字,但这个程序仍然可以正常工作,没有任何警告。

#include <stdio.h>
int main(Mr32) 
{
    printf("why this works?");
    return 0;
}

每当我在mr32的位置写任何东西时,代码仍然能够运行。我真的不知道为什么会发生这种情况。

根据C编程标准来看,这是错误的,对吧?

编辑:我尝试了-Wall,但没有任何警告。

我认为这里应该是错误的,因为我没有按照标准的C函数定义声明进行。

在C中,每个函数定义都必须遵循此格式

return-type function_name ( arg_type arg1, ..., arg_type argN ); 

这也适用于main()函数,对吗..??

好的,-Wextra会显示警告,mr32默认为int类型。

那么为什么main()函数中任何参数的默认类型都是int呢?


3
提高编译器的警告级别并注意警告信息 - pmg
除了缺少 #include <stdio.h> 外,gcc 即使使用 -Wall 也不会抱怨。只有使用 -Wextra 才会抱怨 Mr32 默认为 int。问题更多地涉及默认的 main 参数:哪个规范定义了 main 的类型默认为 int? - Matteo
1
@pmg:是的,gcc -Wextra 会发出警告。但问题是:为什么是警告而不是错误?为什么默认为 int?这在哪里和如何指定? - Matteo
@ Matteo 感谢兄弟...你明白我的问题了。 - Jeegar Patel
尝试使用gcc -std=c89 -pedantic -Wall -Wmissing-parameter-type -Wold-style-definition命令。第一个警告已包含在-Wextra中;第二个警告是独立的。 - pmg
2
@Matteo:在C89的3.5.4.3中指定了可以使用“标识符列表”代替“参数类型列表”。我不确定标准是否明确规定了这些参数默认为“int”,还是因为C89中任何变量默认都是int(即“auto a;”定义了一个自动变量,它是int),所以这只是遵循了这个事实。但是,在3.7.1中有一个示例提到了这样的函数参数的默认值为“int”。 - Steve Jessop
3个回答

8
在K&R C定义中,没有类型的参数默认为int。因此,您的代码对应于:
int main( int Mr32 ) {
    printf("why this works?");
    return 0;
}

请查看以下答案以获取详细信息:C函数语法,参数类型在参数列表之后声明 更新 总结一下:在C89中,K&R声明仍然受支持。
  • undeclared parameter types default to int

    void foo( param )
    

    defaults to

    void foo( int param )
    
  • unspecified return types default to int

    foo()
    

    defaults to

    int foo()
    

注意

虽然这是被支持的,但我永远不会使用它:代码应该易读。


似乎编译器将main()处理为非普通函数.../! - Jeegar Patel
@Mr.32 Matteo在这里告诉你,是的,你可以做到。(但这将取决于你的编译器遵循哪个C标准)。 - nos
+1 Matteo,我认为我得到了答案......你应该更新你的答案并附上一些例子..! - Jeegar Patel
@Matteo 很酷...现在我要接受你的答案了..!人们通常不会阅读评论,所以现在他们将通过你的更新得到答案。谢谢 - Jeegar Patel
既然你说C89,那么这种代码在C99中是否已经过时了? - Lundin
显示剩余3条评论

3
显然,你正在使用一个相当宽松的编译器。这就是标准之王Comeau对其做出的评价:
Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C99 

"ComeauTest.c", line 2: error: standard requires that parameter "Mr32" be given a
          type by a subsequent declaration ("int" assumed)
  int main(Mr32) 
           ^

1 error detected in the compilation of "ComeauTest.c".
In strict mode, with -tused, Compile failed
Hit the Back Button to review your code and compile options. 
Compiled with C++0x extensions enabled.

关于您的编译器在做什么,很难说,因为您没有说明您使用的是哪个编译器。


您说希望遵循 C89 标准。在这种情况下,没有类型信息的参数会被认为是 int 类型。您的 main 函数会被解释如下:

int main(int Mr32)

当然,这仍然不是有效的C代码。在C中有效的main函数如下:
int main(void)
int main(int argc, char* argv[])

你的意思是说这是我的编译器的错误?而且我所做的在C语言标准中是不允许的? - Jeegar Patel
你在编写哪个 C 标准的代码? - David Heffernan
2
可能是将 Mr32 视为 int 参数的名称。这是 GCC 所做的,据我所知,这是 K&R 向后兼容性的一种体现。 - Steve Jessop
然而,如果您选择了c99和“在放松模式下编译”,Comeau只会发出警告,如果您选择了c89/c90,则不会发出任何警告。 - nos

0

由于这似乎是托管程序的代码,除非特定编译器已记录“Mr32”的行为,否则该代码不是有效的C代码。

拥有一个接受除(void)(int argc,char *argv[])之外的其他参数的main()函数是实现定义的行为(C99 5.1.2.2.1)。因此,如果没有关于“Mr32”应该做什么的文档,编译器将不遵循标准。更具体地说,在这个编译器上需要有关于int main(int)语法应该做什么的文档。

这与K&R风格的函数参数无关。我相信C89、C99以及所有C++标准的标准都是一样的。

根据标准中的脚注9),可以接受另一个未命名为argc的int或等效于int的typedef。但在这种情况下,还必须有一个类型为char**的第二个参数,而这里并不是这种情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接