【问题标题】:How is an invalid return type of main() handled by the OS?操作系统如何处理无效的 main() 返回类型?
【发布时间】:2014-07-23 14:46:27
【问题描述】:

我从main()的以下定义开始编程

void main(){}

然后有人告诉我 main() 的这种格式是不好的编程,因为它应该返回 int。他还告诉我,以下 main() 的定义在 C 中是有效的。

int main(void){}

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

今天我尝试使用其他数据类型进行实验,令人惊讶的是,以下所有编译都没有错误。

char main(){}

float main(){}

int* main(){}

甚至编译成功

struct Abc{
int a;
};

struct Abc* main(){}

所以我对此的问题如下:

  • 操作系统如何处理这些意外的返回类型? [我问这个是因为我认为操作系统使用了main() 的返回值]

  • 为什么main()可以返回任意类型?

  • 为什么编译器设计者说 "main() 应该返回 int" 我认为如果他们说 "main() 必须返回没有问题int"?

【问题讨论】:

  • 所以不,main 的返回值通常不是“被操作系统使用”的。
  • @fast:是的,它肯定被操作系统使用,或者至少被操作系统提供。在类 UNIX 系统上,从 shell 执行程序后,它的返回值是$?,用于流控制。 Windows 的行为类似。
  • 我认为问题源于预期,操作系统喜欢以某种方式解释 main 的返回值;我仍然会说它没有(虽然是的,将它解释和传播为 int)

标签: c


【解决方案1】:

如果main 的返回类型既不是int 也不是某个实现定义的类型(其中“实现定义”表示它由实现记录),则行为未定义.

这意味着编译器不需要发出警告或错误消息,但 C 标准没有说明程序的行为方式。

实际行为取决于编译器(调用约定等)和操作系统。

在许多情况下,main(如果有)返回的值将被简单地解释为好像它是 int。如果它返回一个值为1.0double,它可能相当于返回一个int 值1065353216。

否则编译器可能会在编译时拒绝它。否则您的程序可能会崩溃。就 C 标准而言,实际上任何事情都可能发生。

C 中有很多编码错误,编译器不需要以任何特定方式检测或处理。在这种情况下,完全由程序员来解决问题。

只需使用正确的声明即可。对于托管实现,请使用任一

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

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

(对于独立(嵌入式)实现,声明完全由实现定义,入口点可能称为main,也可能不称为main;请参阅编译器的文档。)

至于为什么错误地声明 main 不需要诊断,我不完全确定。它确实使编译器编写者的事情稍微简单了一些。他们可以像对待任何其他函数一样对待main。有 一些 非标准形式实际上是有用的;例如,类 UNIX 系统有时允许

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

第三个参数提供对环境变量的访问。如果必须诊断 main 的错误定义,我个人更喜欢它。

这也在comp.lang.c FAQ 中进行了讨论,从问题 11.12a 开始。

【讨论】:

  • 谢谢,这又是未定义的行为,C 中有多少东西是未定义的
  • @A.s.Bhullar:一大堆。附件 J,C standard 的第 2 小节(这是 C11 的 N1570 草案的 PDF)列出了一些未定义行为的实例;该列表超过 12 页。但更一般地说,标准未定义的任何行为都是未定义的;第 4 节第 2 段明确表示。
【解决方案2】:

操作系统需要 int 类型的返回值并从默认位置获取它(例如,寄存器 EAX)。如果返回其他类型,操作系统将再次获得EAX 的值。没什么特别的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-22
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2018-03-22
    • 2012-10-29
    • 2014-10-20
    相关资源
    最近更新 更多