【问题标题】:Issue with missing forward declaration in C++ [closed]C ++中缺少前向声明的问题[关闭]
【发布时间】:2017-03-15 08:17:54
【问题描述】:

我在C 中编译了以下程序,但没有前向声明函数。它已成功编译并在GCC 中运行,没有任何警告或错误。

#include <stdio.h>

int main()
{
        int ret = func(10, 5);
}

int func(int i, int j)
{
        return (i+j);
}

但是,我在C++ 中编译了以下程序而没有前向声明函数,编译器给了我一个错误。

#include <iostream>
using namespace std;

int main()
{
        int ret = func(10, 5);
}

int func(int i, int j)
{
        return (i+j);
}

一个错误:

fl.cpp:6:22: error: ‘func’ was not declared in this scope
  int ret = func(10, 5);
                      ^

为什么 C++ 编译器会出错?是不是默认采用int数据类型?

【问题讨论】:

  • 从不在 C++ 中,从 99 开始就不再在 C 中了
  • “为什么 C++ 编译器会出错?” 像往常一样:因为标准是这样说的。
  • @CraigYoung 将其读作“no fwd decl ...”
  • 问题标题是否只是抱怨,说明 C++ 需要在使用函数之前进行声明,因此在某些情况下需要“前向声明”?
  • @SouravGhosh - 具有讽刺意味的是,现代 C 和 C++ 同意这一点:)

标签: c++ c forward-declaration function-prototypes


【解决方案1】:

嗯,它在 C 中的错误与在 C++ 中一样多。

考虑到这个问题是基于“假设”,即从 C 编译器的角度来看代码是有效的,让我详细说明一下,根据规范 ( C11),不允许隐式声明函数。用严格的一致性编译你的代码,(任何符合的)编译器都会在 C 语言中产生同样的错误。

See live example

引用C11,前言/p7,“第二版的主要变化包括:”

  • 移除隐式函数声明

同样的存在于C99中。


注意:为什么它可能会起作用

PreC99,其实这段代码还有编译成功的空间。在缺少函数原型的情况下,假定函数返回 int 并接受任意数量的参数作为输入。现在这是非常不标准的,具有遗留支持的编译器可能会选择允许编译此类代码,但严格来说,符合标准的编译器应该拒绝这样做。

【讨论】:

  • 符合 C99 或更高版本的编译器将拒绝该代码。早于 1999 年或处于“C89”模式(例如gcc -stdc89)的编译器通常不声称符合 C99。
  • @Peter 有时您需要使用选项强制执行“合规性”,默认情况下它不存在......这就是我要说的。
【解决方案2】:

为什么 C++ 编译器会报错?

因为您不应调用尚未在 C++ 中声明的函数。

是不是默认取int数据类型?

没有。在另一种语言 C 中曾经是这种情况。在 C++ 中不是这种情况(在后来的标准版本中也不是在 C 中)。

【讨论】:

    【解决方案3】:

    在 C++ 中,您不能调用未声明的函数。在 C 中,如果函数的定义返回 int,则可以在没有前向声明符的情况下调用函数。这是因为旧的 K&R 函数定义样式。这对于 ANSI-C 来说已经过时了,总是用原型声明一个函数。

    【讨论】:

    • 这有点正确,但大多是非常错误的。当遇到一个未声明的函数时,C 编译器会假设一个声明(如果没有找到实现,链接器会报错)。当假设为假时,即在代码后面找到声明或实现时,
    • 并且与假设不匹配,给出编译器错误。这可能会进一步受到您的编译器版本和编译器标志的影响。到目前为止,最好的建议是:不要这样做;总是提前声明。
    • @parvus,是的,C 编译器假定一个声明。这是旧的 K&R C 函数样式的遗留物,其中函数声明符没有参数,如果函数返回一个 int,则声明很可能已被省略。
    【解决方案4】:

    完成图片并与Sourav Ghosh的答案相关。以下是 C++ 标准对这个问题的看法:

    [expr.call] p2:

    [ 注意:如果使用函数或成员函数名称,并且名称查找未找到该名称的声明,则程序格式错误。这样的调用不会隐式声明任何函数。 — 尾注 ]

    没有比这更明确的了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 2016-12-17
      相关资源
      最近更新 更多