【问题标题】:#include headers in C/C++#include C/C++ 中的头文件
【发布时间】:2011-01-30 08:55:34
【问题描述】:

在阅读了几个有关编译问题(尤其是 C++)的问题并注意到在许多情况下问题是缺少标头 #include。我不禁怀疑自己的无知并问自己(现在问你):

为什么没有自动检查缺失的标头并添加或请求给程序员?

例如,Netbeans 中的 Java 导入语句可以使用此类功能。

【问题讨论】:

  • java 是否可以处理头文件?
  • 它们被称为导入语句
  • Java 的 import 更像 C++ 的 using,而不像 #include
  • import 语句根本不是一回事。

标签: c++ c include header


【解决方案1】:

还记得java.util.Datejava.sql.Date 在Java 中的冲突吗?如果有人在他们的代码中使用了Date,你无法判断他们是忘记了import java.util.Date还是import java.sql.Date

在 Java 和 C++ 中,都无法确定缺少什么 import/include 语句。所以两种语言都没有尝试。您的 IDE 可能会为您的代码中使用的未声明符号提供建议。

这个问题在 C++ 中更加复杂,因为标准规定任何标准头文件都可以包含任何其他标准头文件。因此,在不直接包含定义它的头文件的情况下使用函数或类非常容易,因为您的编译器恰好间接包含了正确的头文件。结果代码在某些实现中有效,但在其他实现中无效,具体取决于它们是否共享该标头依赖项。

C++ IDE 通常无法判断头文件依赖项是“有保证的”,还是只是用户不应依赖的附带实现细节。显然,对于标准库,它可能只知道在什么标头中定义了什么,但是一旦您进入第三方库,它就会变得非常不确定。

我认为大多数 C++ 程序员都希望必须查找哪些标头定义了哪些符号。使用 Java,每个文件一个公共类的规则大大简化了这一点,您只需导入所需的包/类。 C++ 没有包,IDE 查找名为my_namespace::something::MyClass 的类的唯一方法是在每个头文件中搜索它。

【讨论】:

    【解决方案2】:

    为什么没有自动检查缺失的标头并添加或请求给程序员?

    但它们会被自动检查。

    1. 我的编译器在找不到头文件时编译失败。
    2. 当我的 IDE (eclipse) 找不到我 #included 的头文件时,它会添加一个视觉线索,它会在 #include 行下划线并提供一个工具提示,告诉我问题出在哪里。

    它不会自动添加包含,因为它不知道我忘记了哪个包含。编译器不是通灵的。

    【讨论】:

      【解决方案3】:

      最后我记得,如果遗漏了 Import 语句,Java 也会抛出错误。 NetBeans GUI 让您的生活更轻松。

      或许您应该尝试为您的 C/C++ 代码寻找智能 GUI。

      【讨论】:

        【解决方案4】:

        因为您信任计算机会为您思考的那一刻,您手上就有一个 SkyNet 的重大案例。

        一般来说,除了非常简单的选择之外,计算机在做出选择方面都非常糟糕。将某些东西从依赖地狱中拉出来根本不是您应该委托给它的任务,因为这种想法会导致草率的编码和错误的代码。

        【讨论】:

          【解决方案5】:

          如果我引用了一个名为sqrt 的函数,如果我没有指定,编译器如何知道要查看哪个文件?它绝对可以是我整个硬盘驱动器上的任何文件。

          与 Java 不同,C++ 并不真正将任何文件视为“特殊”文件。 Java 有其庞大(臃肿)的类库,程序员可以自动访问它。

          在 C++ 中,这个概念不存在。您告诉编译器要搜索的路径,并且每当您#include 一个文件时,它都会在这些路径中搜索文件名。

          如果碰巧找到一个标准库文件,它将使用它。如果它碰巧找到了第三方文件,它会使用它。

          编译器不知道 sqrt 是在标头math.h 中定义的。或者说它 通常定义在cmath 中。实际上,由标头定义的函数可能变化。也许,如果我#define 适当的预处理器符号,一些函数将从特定的头文件中删除,而其他函数将被启用。

          但与 Java 不同,在 Java 中,库定义的函数和类可以通过检查库文件的元数据来确定,在 C++ 中,必须编译标头。并且编译的结果可能会因包含它的上下文而异。

          所以 C++ 编译器不能猜测应该包含哪个标头来定义您刚刚使用的函数。

          【讨论】:

            【解决方案6】:

            编译器不必为您考虑。如果两个不同的库中存在同名函数怎么办?它如何知道要包含哪个标头以及要链接哪个库?在我看来,让编译器或 IDE 默默地修复你草率的代码是个坏主意。

            【讨论】:

              【解决方案7】:

              差异的部分原因在于两者之间做出的一些基本设计决策不同。特别是,Java 要求类的名称与文件的名称匹配,因此您使用的类的名称几乎可以告诉它您需要导入什么。

              在 C 或 C++ 中,您为标题指定的名称不一定要与内容匹配。如果您非常想将标题命名为 1.h、2.h、3.h 等等,甚至可以命名为 1.bas、2.pas、3.java、4.ada 等等您碰巧喜欢的误导性名称。这显然是个糟糕的主意,但如果你还是这样做了,编译器就不会被打扰了。

              因此,C 或 C++ 工具很难猜测需要包含哪些标头才能获得特定类型的定义。理论上,它可以(例如)在您编写的所有标题中构建一个包含所有函数、类、类型等的大型数据库,并且当您使用一个时,告诉您哪些标题定义了哪些名称,但我不知道实际上有一个 IDE 这样做。

              【讨论】:

                【解决方案8】:

                NetBeans 是一个 IDE(集成开发环境)。一些 C/C++ IDE 确实具有该功能......但并不是每个人都知道或使用它。

                【讨论】:

                  【解决方案9】:

                  因为通常很难知道需要包含哪些头文件才能正确定义某些内容。让您的 IDE 能够猜测简单的案例并提供帮助,这将是一个非常好的功能。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2022-10-12
                    • 1970-01-01
                    • 2016-07-31
                    • 2010-12-26
                    • 2012-09-01
                    • 2014-02-12
                    • 1970-01-01
                    相关资源
                    最近更新 更多