2010-03-22 100 views
6

在阅读了关于编译问题(特别是C++)的几个问题之后,注意到在很多情况下这个问题是缺少头文件#include。我忍不住想知道我的无知,并问自己(现在给你):#include在C/C++头文件

为什么缺少的标题不会自动检查,并添加或请求程序员?

此类功能可用于Netbeans中的Java导入语句。

+4

java是否可以处理头文件? – Peter 2010-03-22 14:12:26

+0

它们被称为import语句 – bragboy 2010-03-22 14:13:52

+2

Java的'import'更像是C++的''using'',而不像'#inc'。 – fredoverflow 2010-03-22 14:26:12

回答

12

请记住在java.util.Datejava.sql.Date之间的Java冲突吗?如果有人在他们的代码中使用Date,则无法分辨他们是否忘记了import java.util.Dateimport java.sql.Date

在Java和C++中,都无法确定地告诉缺少import/include语句。所以这两种语言都不会尝试您的IDE可能会针对代码中使用的未声明的符号提出建议。

这个问题在C++中更加复杂,因为标准说任何标准头文件都可以包含任何其他标准头文件。因此,使用函数或类时非常容易,不需要直接包含定义它的头文件,因为编译器会间接地包含正确的头文件。根据它们是否共享该标题依赖关系,所得到的代码在某些实现中工作,但不在其他代码中工作。

C++ IDE通常不可能判断头文件依赖性是“保证”还是只是用户不应该依赖的附带实现细节。很显然,对于标准库,它可能只知道在哪些头文件中定义了什么,但只要您到达第三方库,它就很不确定。

我认为大多数C++程序员希望能够查找哪些头文件定义了哪些符号。使用Java,单一公用类每文件规则可以大大简化这一操作,并且只需导入所需的软件包/类。 C++没有包,并且IDE找到名为my_namespace::something::MyClass的类的唯一方法是在每个头文件中搜索它。

+0

感谢您的解释史蒂夫 – Carlos 2010-03-22 17:31:09

0

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

2

因为第二你相信电脑认为为你,你有一个重大案件的SkyNet在你手上。

一般而言,电脑在做出选择时非常糟糕,除非是非常简单的电脑。从依赖性地狱中拉出一些东西根本不是你应该委托它的任务,因为那种想法导致了潦草的编码和错误的代码。

4

最后我记得,如果导入语句错过,Java也会报错。这是NetBeans GUI,让您的生活更轻松。

可能您应该尝试为您的C/C++代码找到智能GUI。

7

为什么丢失的标题不会自动检查并添加或向程序员请求?

但它们会自动检查。

  1. 我的编译器无法找到标题时编译失败。
  2. 我的IDE(eclipse)添加了一个视觉线索,它无法找到我包含的头文件,它强调了#include行并提供了一个工具提示,告诉我问题是什么。

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

0

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

1

编译器不应该为你考虑。如果在两个不同的库中有同名的函数呢?它如何知道要包含哪个头和链接哪个库?在我看来,让一个编译器或IDE静静地修复你的草率代码是一个坏主意。

1

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

在C或C++中,您给标题的名称根本不一定与内容匹配。如果你想足够糟糕,你可以将你的头文件命名为1.h,2.h,3.h,等等 - 甚至是1.bas,2.pas,3.java,4.ada和其他任何其他的误导你的名字你喜欢。这显然是一个糟糕的主意,但如果你这样做了,编译器一点都不会困扰。因此,C或C++工具更难以猜测需要包含哪些头部以获得特定类型的定义。理论上,它可以(例如)在你编写的所有头文件中构建一个包含所有函数,类,类型等的大型数据库,并且当你使用它时,告诉你哪些头文件定义了什么名称,但我不知道实际上是这样做的IDE。

2

如果我参考一个名为sqrt的函数,如果我没有指定它,编译器如何知道要查找哪个文件?它可以是我整个硬盘上的任何文件。

与Java不同,C++并没有真正考虑任何“特殊”文件。 Java拥有巨大的(膨胀的)类库,程序员可以自动访问它。

在C++中,这个概念不存在。你告诉编译器搜索哪些路径,并且每当你包含一个文件时,它将在这些路径中搜索文件名。

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

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

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

因此,C++编译器不能猜测应该包含哪个头以便定义刚刚使用的函数。

+0

感谢好友,使很多感觉 – Carlos 2010-03-22 17:30:39

相关问题