首页 文章

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

提问于
浏览
5

标准说:

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

2 回答

  • 2

    您对该标准的引用表明"some other implementation-defined manner" . 似乎gcc在允许的范围内非常自由,因为 main 的签名;它似乎忽略了你传递的参数 . 如果使用 gcc -Wall 进行编译,则会收到有关main的原型不符合预期的警告 .

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

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

  • 2

    从标准一致性开始:

    1在本国际标准中,“应”应被解释为对实施或计划的要求;相反,“不得”应被解释为禁止 . 2如果违反了约束或运行时限制之外出现的''shall''或''shall not'要求,则行为未定义 . [...]

    现在看看你引用的标准强调:

    [...] . 应使用返回类型int和[...]定义它 .

    在这种情况下,

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

    "shall"要求超出约束条件,因为标准明确规定 main 返回类型应为 int ,或者没有参数

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

    或者有两个参数

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

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

相关问题