调用带有错误签名的main()函数

时间:2014-06-28 09:10:39

标签: c main

标准说:

  

5.1.2.2.1程序启动

     

程序启动时调用的函数名为main。该   实现声明此函数没有原型。应该是   使用返回类型int定义并且没有参数:int   main(void){/ * ... * /}或带有两个参数(在此称为   argc和argv,虽然可以使用任何名称,因为它们是本地的   声明它们的函数):int main(int argc,char argv [])   {/ ... * /}或同等的; 10)或其他一些   实现定义的方式。

如果我写这个:

#include <stdio.h>

struct some_struct
{
    int i;
};

float main(struct some_struct s)
{
    printf("Why does this main get called?\n");
}

实际上,正如我所见,它会被任何原型调用,并且没有任何运行时错误。

为什么禁止它?这没有理由吗?另外,如果签名错误,如何调用它?

我使用了gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

3 个答案:

答案 0 :(得分:2)

您对该标准的引用表明&#34;其他一些实现定义的方式&#34;。似乎gcc在允许main的签名方面非常宽松;它似乎忽略了你传递的参数。如果使用gcc -Wall进行编译,则会收到有关主要原型不符合预期的警告。

对于主要的原型,clang不太宽容。它将接受带有警告的返回类型float,但会在struct参数上出错。

C仅按名称查找函数,因此链接器不关心异常返回类型和参数。

答案 1 :(得分:2)

从标准一致性开始:

  

1在本国际标准中,''shall''应被解释为对a的要求   实施或计划;相反,''不应该'被解释为   禁止。

     

2如果违反约束或运行时限制之外的''应'或''不得''要求行为未定义 。 [...]

现在看看你引用标准的重点:

  

[...]。 必须用返回类型int和[...]

定义

在这种情况下,

float main(struct some_struct s){...}  

“必须”要求不在约束范围内,因为标准明确规定main返回类型应为int,不带参数

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

或有两个参数

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

这意味着您的程序行为未定义

答案 2 :(得分:0)

在C语言中,如果函数签名未指定任何参数,则意味着可以使用任意数量的参数或不使用任何参数来调用函数。

嘿,请签出此链接-https://www.geeksforgeeks.org/difference-int-main-int-mainvoid/