【问题标题】:Why do programs in C compile even when the return statement is missing? [duplicate]为什么即使缺少 return 语句,C 中的程序也能编译? [复制]
【发布时间】:2012-06-07 04:10:02
【问题描述】:

我在 C 中实现了一些基本的数据结构,我发现如果我从函数中省略返回类型并调用该函数,编译器不会产生错误。我用cc file.c 编译并且没有使用-Wall(所以我错过了警告)但是在其他编程语言中这是一个严重的错误并且程序不会编译。

根据 Graham Borland 的要求,这里有一个简单的例子:

int test() 
{
  printf("Hi!");
}

int main() 
{ 
    test();
}

【问题讨论】:

  • 那里没有缺少返回类型。
  • @ta.speot.is 他的意思可能是返回声明。我的回答已经反映了两者。
  • @Matt 是的,没错,谢谢!

标签: c


【解决方案1】:

函数的返回类型是可选的,如果未指定,则视为“int”。

【讨论】:

    【解决方案2】:

    这是因为在 C 中,任何变量/函数都隐含为int

    这与您可以使用register 代替register int、或unsigned 代替unsigned intauto 代替auto intstatic 代替static int 的原因相同。我个人总是用int 明确限定我的变量,但是否这样做是你的选择。

    【讨论】:

    • +1 用于回答问题,尽管该示例似乎表明 OP 想要别的东西。
    【解决方案3】:

    C 是一门古老的语言,在它被引入的时候,返回整数已经足够普遍,可以作为函数的默认返回类型。人们后来开始意识到,对于更复杂的返回类型,最好指定 int 以确保您不会忘记返回类型,但为了保持与旧代码的向后兼容性,C 无法删除此默认行为。相反,大多数编译器都会发出警告。

    如果函数在没有返回语句的情况下到达末尾,则返回未定义的值,main 函数除外,则返回 0。原因同上。

    /* implicit declaration of printf as: int printf(int); */
    
    /* implicit int type */
    main()
    {
        printf("hello, world\n");
    } /* implicit return 0; */
    

    【讨论】:

    • 如果您回溯到足够远(80 年代中期或更早),则没有返回类型为 void;所以一个没有真正返回值的函数仍然被认为返回一个int。但是,如果您从未使用过该值,那么函数末尾是否没有返回也没关系。另请注意,在 C89 中,如果您没有显式返回值,则来自 main 的返回值是未定义的。只有在 C99 中,才定义从 main() 的末尾脱落等同于 return 0;。这部分是为了遵循 C++98 的领先地位,它也定义了这种行为。
    • @Jonathan void 在 PWB 的 C 中,早于 80 年代。
    • 也许;但它不在我在 1983-4 年学习的 C 语言中。它可能在 3 年后到达。这取决于您使用的编译器。
    • nitpick,不是未定义的返回值,而是未定义的整个程序的行为,它是否会尝试访问函数的返回值。因此,如果您这样做(尝试访问该值),它可能会吃掉您的硬盘或清空您的银行帐户。而main 则不同(自 C99 起),因为它是标准中指定的显式异常。
    • @JonathanLeffler 我回答中的例子是对 Kernighan 和 Ritchie 的第一版中第一个程序的精确测试 The C 编程 语言(1978年出版)。请注意缺少 return 语句和 #include <stdio.h>(后者在第二版中添加)。
    【解决方案4】:

    该函数不会像上面的答案所说的那样返回 0。实际上,printf 返回一个值:打印的字符数。在您的情况下,printf 是您的测试函数中的最后一个表达式,它将返回 3。因此函数 test 将返回 3。

    【讨论】:

    • 肯定是未定义的行为...
    • 啊,确实,根据这条评论:stackoverflow.com/a/2598133/1295368 我描述的行为仅适用于 x86 平台,但显然未定义。
    • C 不是表达式语言;函数返回最后一个表达式的值。
    【解决方案5】:

    到目前为止,我还没有看到任何答案中很好地解决了为什么。在 C 中,具有非 void 返回类型的函数在没有返回语句/值的情况下结束是完全合法的,只要调用者不尝试使用返回值。例如(有点不平凡的例子):

    #include <stdio.h>
    int foo(int want_result)
    {
        puts("hello");
        if (want_result) return 42;
    }
    
    int main()
    {
        foo(0);
        printf("%d\n", foo(1));
    }
    

    这个例子有点做作,但如果返回类型是一个巨大的结构并且需要很长时间才能返回,它实际上可能变得有意义。

    【讨论】:

      猜你喜欢
      • 2013-12-22
      • 2018-05-18
      • 2013-05-23
      • 1970-01-01
      • 2021-06-10
      • 2017-03-17
      相关资源
      最近更新 更多