【问题标题】:Using return 0 with void main()?将 return 0 与 void main() 一起使用?
【发布时间】:2019-01-01 11:56:24
【问题描述】:

我只是想看看如果我将return 0 语句与void main() 一起使用会发生什么。我原以为编译器会给出一个错误,但它只是给出一个警告并成功执行了程序,但最后返回了一些非零值,现在我怀疑为什么程序执行时没有错误,然后当我返回一些值时用过void main()

#include<stdio.h>

void main()
{
    printf("Hello World\n");
    return 0;
}

【问题讨论】:

  • 这个程序不是有效的 C 程序。任何编译它的 C 编译器都是按照“grabage in - garbage out”的原则来做的。行为未定义。所以,无论你“成功执行”什么,都与 C 语言无关。
  • @AnT:这不是 undefined 行为。 C99 规范指出允许符合要求的实现来执行此操作,并要求它是实现定义的 行为。如果您不清楚其中的区别,请进行网络搜索,一切都会变得清晰。
  • @AnT 是的,一些编译器允许void main 并且没有任何问题,如果您不关心返回值,这只是一个捷径。埃里克是对的
  • @Eric Lippert:绝对错误!究竟“允许做什么”什么?在所有 C 编译器中,void 函数中的 return 0约束冲突。没有例外。每个 C 编译器都需要对此代码发出诊断。之后,行为未定义。未定义实现,但明确未定义

标签: c return void


【解决方案1】:

main 的这个返回值通常用于程序运行所在的操作系统来确定执行期间是否存在错误,通常值 0 表示成功,其他值按惯例解释为错误。

【讨论】:

  • 将零解释为成功不仅是典型的;它由 C 标准指定。
  • 确实如此,但是在不完全符合 C 或在我通常提到的标准之前开发的系统中。
【解决方案2】:

我怀疑为什么程序没有错误地执行,然后当我使用 void main() 时还返回一些值

C 标准说正确的做法是int main,并且允许符合要求的实现允许main 上的其他签名,如果它愿意的话。

显然您的实现选择允许这种非标准用法,并且它表现出的行为是编译时的警告,然后是运行时观察到的行为。

但你已经知道了。编译器做编译器所做的事情,因为编译器作者是这样写的。如果您想知道他们做出这些选择的原因,请询问他们。由于您还没有说您使用的是什么编译器,所以我们没有更多的事情要做。

【讨论】:

  • 问题不是关于void main,而是关于void 函数中的return 0
  • @AnT 即使void 函数中的return 0 是否被允许,main() 也有可能不同的附加规范。假设问题“将 return 0 与 void main() 一起使用?”大约是main() 而不是一般的功能是合理的。
  • @chux:虽然main 确实有“附加规范”,但它们都不允许这样做。所以,不,main 的“附加规范”与此无关。
【解决方案3】:

您的代码不是有效的 C 代码。 C 语言不允许您在 void 函数中使用 return 0。这是一个违反约束,即我们俗称的错误。每个符合标准的 C 编译器都需要为此代码发出诊断消息,然后从标准 C 语言的角度来看,您的代码的行为是未定义的。

根据您的描述,您的编译器确实根据语言规范的要求对此代码发出了诊断消息。之后,您从编译代码中观察到的任何行为可能(或可能不)由您的特定编译器定义,但不再由语言本身定义。

【讨论】:

  • 好详细的答案!
【解决方案4】:

在返回void 的函数中使用return 0;违反约束

6.8.6.4 返回语句

约束

1 带有表达式的return 语句不应出现在返回类型为 是void。没有表达式的return 语句只能出现在函数中 其返回类型为void

C 2011 online draft

编译器必须发出约束违规诊断(您在编译期间看到的警告) - 但是,编译器可能继续翻译程序并生成可执行文件(警告和错误之间的区别,以及是否停止翻译,取决于实现)。

其次,除非您的编译器文档明确void 列为 main 的有效返回类型,否则使用 void main 会导致未定义的行为 - 此时,编译器不需要以任何特定的方式处理这种情况。

通常,试图弄清楚如何从未定义的行为中得到特定结果是浪费时间,因为该行为可能无法重复。在这种情况下,您告诉编译器main 不会返回值,它会相应地生成机器代码。用于该返回值的寄存器很可能在 main 返回后立即被覆盖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-25
    • 2016-01-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    相关资源
    最近更新 更多