调用具有错误签名的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


从标准一致性开始:

1在本国际标准中,“应”应解释为执行或程序的要求; 相反,“不得”被解释为禁止。

2如果违反约束条件或运行时间约束条件以外的“应”或“不得”要求被违反,则行为不确定 。 [...]

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

[...]。 它应该用int的返回类型和[...]

在这种情况下,

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

“应”的要求不受约束,因为标准明确指出main返回类型应该是int或者不带参数

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

或者带有两个参数

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

这意味着你的程序的行为是不确定的。


您从标准中引用的“一些其他实现定义的方式”。 看起来,gcc在允许的main签名方面非常自由, 它似乎忽略了你传递的参数。 如果使用gcc -Wall编译,您会收到有关main的原型不符合预期的警告。

铿锵声对主要的原型不太宽容。 它会接受带有警告的float返回类型,但会在struct参数中出错。

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

链接地址: http://www.djcxy.com/p/28745.html

上一篇: main() function with wrong signature gets called

下一篇: What was the rationale for making `return 0` at the end of `main` optional?