【问题标题】:why "int main(anything_you_type)" doesnt produce any error?为什么“int main(anything_you_type)”不会产生任何错误?
【发布时间】:2011-11-25 20:43:33
【问题描述】:

在这里,我在主参数声明中写下了我的名字,但这个程序仍然有效并且没有给出任何警告。

#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 呢?

【问题讨论】:

  • 提高编译器的警告级别并注意警告
  • 除了缺少的#include &lt;stdio.h&gt;,即使使用-Wall,gcc 也不会抱怨。只有-Wextra 它抱怨Mr32 默认为int。问题更多的是关于默认的主要参数:哪个规范定义了主要的类型默认为 int?
  • @pmg: 是的gcc -Wextra 抱怨。但问题是:为什么是警告而不是错误?为什么默认为int?这是在哪里以及如何指定的?
  • @Matteo 谢谢兄弟...你有我的问题..
  • @Matteo:它在 C89 的 3.5.4.3 中指定,它允许使用 identifier-list 而不是 parameter-type-list。我不确定标准是否在规范文本中明确声明参数被假定为int,或者这是否只是因为 C89 中的任何变量默认情况下都是 int(即auto a;定义了一个自动变量,它是一个 int),但在 3.7.1 中有一个示例确实提到 int 是此类函数参数的默认值。

标签: c gcc compiler-construction error-handling main


【解决方案1】:

显然您使用的是相当松散的编译器。这就是科莫国王的标准:

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 语言标准中是不允许的?
  • 你编码的 C 标准是什么?
  • 它可能将Mr32 用作int 参数的名称。这就是 GCC 所做的,而 AFAIK 它是 K&R 向后兼容的东西。
  • 不过,Comeau 只有在勾选 c99 和“以宽松模式编译”时才会发出警告,如果选择 c89/c90 则不会发出警告
【解决方案2】:

在 K&R C 定义中,没有类型的参数默认为 int。然后您的代码对应于

int main( int Mr32 ) {
    printf("why this works?");
    return 0;
}

详情请看这个答案:C function syntax, parameter types declared after parameter list

更新

总结一下:在 C89 中仍然支持 K&R 声明

  • 未声明的参数类型默认为 int

    void foo( param )
    

    默认为

    void foo( int param )
    
  • 未指定的返回类型默认为 int

    foo()
    

    默认为

    int foo()
    

注意

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

【讨论】:

  • 似乎编译器处理 main() 不像 normail 函数.../!
  • 在正常的函数定义中你不能写成 int f00 (mr32){ }
  • @Mr.32 Matteo 告诉你,是的你可以。 (但这将取决于您的编译器遵循哪个 C 标准)。
  • @Mr.32:K&R 风格定义适用于每个功能。你可以写void foo(varname)
  • @Mr.32 in c89, int foo(bar,baz)int foo(int bar,int baz); 相同,这意味着如果您不给函数参数指定类型,则参数将被隐式视为 int。这是从 K&R C 继承的功能,它是 C89 之前的“标准”。函数返回类型也一样,如果省略它,它将默认为 int。
【解决方案3】:

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

拥有一个接受除(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** 类型的第二个参数,这里不是这种情况。

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    相关资源
    最近更新 更多