【问题标题】:Unexpected success of C CodeC 代码的意外成功
【发布时间】:2013-11-14 04:58:21
【问题描述】:

我正在 Code::Blocks v 12.11 中测试以下代码:

#include <stdio.h>

int main()
{
    display();
    return 0;
}

void display()
{
    printf("\nHi");
}

它编译成功并且运行良好。我无法理解为什么? 我的查询如下:

  1. 在 C/C++ 中使用之前,至少需要声明一个函数或变量。这里,在我们调用函数 display() 之前没有声明。

  2. 1234563它是 void display()。

【问题讨论】:

  • 你是对的,一个函数应该在c之前声明,否则它会出错。
  • 你的第二点是错误的。您已经定义了一个返回类型 void 并且您的函数返回 void。我认为函数没有默认返回类型 - 您必须将返回类型定义为函数定义的一部分。
  • @FaddishWorm 不,在 C90 中,如果函数尚未声明,则假定它们返回 int。因此int main(void){ int x = 1 + f(); return x; } 编译,如果f() 被假定返回void,则不会编译。

标签: c++ c


【解决方案1】:

在 C++ 中,函数必须在使用前声明或定义;该代码不能是 C++。

在 C89 或准标准 C 中,如果编译器遇到一个标识符后跟一个左括号,则它是一个函数调用,如果没有有效的声明或定义,则返回类型隐式为 int 和参数的数量和类型未指定。 (因此,在示例中,display() 是一个函数,返回一个 int 并采用不定的——但不是可变的——参数数量。)

在 C99 或 C11 中,在任何严格遵从模式下,您必须在调用之前在范围内声明或定义函数。它仍然不必是原型(推断的声明int display(); 不是原型,定义也不是原型——它必须是int display(void) 才能提供原型!)。

由于display() 的推断类型和相互矛盾的定义,我相信你应该得到一个编译错误。即使在 C89 模式下,它充其量只是一个允许它通过的草率编译器。确实,我认为即使是预标准编译器也应该抱怨假定返回类型和实际返回类型之间的差异,但是当然没有标准,所以你不能抱怨(而且,无论如何,该标准现在已经 24 岁了— 只支持接近过时的编译器)。

您在哪个平台上使用哪个编译器(和版本)?

Mac OS X 10.9 上的 GCC 4.8.2,即使设置尽可能宽松,说:

dec.c:9:6: warning: conflicting types for ‘display’ [enabled by default]
 void display()
      ^
dec.c:5:5: note: previous implicit declaration of ‘display’ was here
     display();
     ^

【讨论】:

  • 大多数版本的 GCC 无论如何都会发出代码 - 请注意,这只是一个警告,它满足编译器“必须诊断”的旧标准。要将其变为错误,请使用-pedantic-errors,或者最好养成使用-Werror 编译所有内容的习惯(将所有错误视为警告)并保持代码干净(er)。
  • 没错,这只是一个警告。我忘记了人们可能会尝试运行代码,尽管在编译过程中会出现警告——我没有,而且我使用了相当严格的选项来确保没有任何警告比这个更晦涩的问题。
  • 我在 Windows7 上使用了 Code::Blocks 版本 12.11。更多细节在这里给出:codeblocks.org/features
【解决方案2】:

您的代码作为 .c 文件运行良好,但在作为 .cpp 文件执行时显示错误 我希望这篇文章能解释原因。

Why are function declaration mandatory in C++ and not in C?

【讨论】:

    猜你喜欢
    • 2013-10-31
    • 2016-02-04
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多