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



标准规定:

5.1.2.2.1程序启动

程序启动时调用的函数命名为main。的实现没有为这个函数声明原型。它应该是用返回类型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在本国际标准中,"应"被解释为对实施或程序的要求;反之,"不得"则被解释为禁止。

如果"应该"或"不应该"需求出现在约束或运行时约束之外,则行为是未定义的。[…]

看你引用的段落的重点:

[…]。应定义为返回类型int和[…]

在这种情况下,

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

"shall"要求不在约束范围内,因为标准明确规定main返回类型为int或者不带参数

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

或带两个参数

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

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

您在标准中引用的是"一些其他实现定义的方式"。看来gcc在允许什么作为main的签名方面是相当自由的;它似乎忽略了您传递的参数。如果你用gcc -Wall编译,你会得到关于main的原型不是它所期望的警告。

clang对main的原型不太宽容。它将接受返回类型float并给出警告,但会在struct参数上出错。

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

在C语言中,如果一个函数签名没有指定任何实参,这意味着该函数可以带任意数量的形参调用,也可以不带任何形参。

嘿,看看这个链接- https://www.geeksforgeeks.org/difference-int-main-int-mainvoid/

相关内容

  • 没有找到相关文章

最新更新