简体   繁体   English

C / C ++中的#include标头

[英]#include headers in C/C++

After reading several questions regarding problems with compilation (particularly C++) and noticing that in many cases the problem is a missing header #include. 在阅读了有关编译问题的几个问题(特别是C ++)并注意到在许多情况下问题是缺少标题#include。 I couldn't help to wonder in my ignorance and ask myself (and now to you): 我忍不住想知道我的无知并问自己(现在对你):

Why are missing headers not automatically checked and added or requested to the programmer? 为什么缺少标题不会自动检查并添加或要求程序员?

Such feature is available for Java import statements in Netbeans for example. 例如,此类功能可用于Netbeans中的Java导入语句。

Remember the clash in Java between java.util.Date and java.sql.Date ? 还记得java.util.Datejava.sql.Date之间的Java冲突吗? If someone uses Date in their code, you can't tell whether they forgot import java.util.Date or import java.sql.Date . 如果有人在他们的代码中使用Date ,则无法判断他们是否忘记import java.util.Dateimport java.sql.Date

In both Java and C++, it is not possible to tell with certainty what import/include statement is missing. 在Java和C ++中,无法确定缺少哪些import / include语句。 So neither language tries. 所以两种语言都没有尝 Your IDE might make suggestions for undeclared symbols used in your code. 您的IDE可能会为代码中使用的未声明符号提供建议。

The problem is further complicated in C++, because the standard says that any standard header can include any other standard header(s). C ++中的问题更加复杂,因为标准规定任何标准头文件都可以包含任何其他标准头文件。 It's therefore very easy to use a function or class without directly including the header which defines it, because your compiler happens to include the right header indirectly. 因此,在不直接包含定义它的头的情况下使用函数或类非常容易,因为您的编译器恰好间接包含了正确的头。 The resulting code works in some implementations but not others, according to whether they share that header dependency. 根据它们是否共享该头依赖性,生成的代码在某些实现中起作用,但在其他实现中起作用。

It's not in general possible for a C++ IDE to tell whether a header dependency is "guaranteed", or just an incidental implementation detail that users shouldn't rely on. 一般来说,C ++ IDE无法判断标头依赖性是否“有保证”,或者仅仅是用户不应依赖的附带实现细节。 Obviously for standard libraries it could just know what's defined in what headers, but as soon as you get to third party libraries it gets quite uncertain. 显然,对于标准库,它可以只知道在什么标题中定义了什么,但是一旦到达第三方库,它就变得非常不确定。

I think most C++ programmers expect to have to look up what headers define what symbols. 我认为大多数C ++程序员都希望查找哪些标头定义了哪些符号。 With Java, the one-public-class-per-file rule simplifies this considerably, and you just import the packages/classes you want. 使用Java,one-public-class-per-file规则大大简化了这一点,您只需导入所需的包/类。 C++ doesn't have packages, and the only way for the IDE to find a class called my_namespace::something::MyClass is to search for it in every header file. C ++没有包,IDE找到名为my_namespace::something::MyClass的类的唯一方法是在每个头文件中搜索它。

Why are missing headers not automatically checked and added or requested to the programmer? 为什么缺少标题不会自动检查并添加或要求程序员?

But they are automatically checked. 但它们会自动检查。

  1. My compiler fails compilation when it can't find a header. 当找不到标题时,我的编译器无法编译。
  2. My IDE (eclipse) adds a visual clue when it can't find a header file I've #included, it underlines the #include line and provides a tooltip telling me what the problem is. 我的IDE(eclipse)添加了一个视觉线索,当它找不到我已经#include的头文件时,它会强调#include行,并提供一个工具提示,告诉我问题是什么。

It won't automatically add an include because it can't know which include I forgot. 它不会自动添加一个包含因为它无法知道哪些包含我忘了。 Compilers aren't psychic. 编译器不是通灵的。

Last I remember, Java also throws error if an Import statement is missed. 最后我记得,如果错过了Import语句,Java也会抛出错误。 It is the NetBeans GUI that makes your life easier. NetBeans GUI使您的生活更轻松。

Probably you should try finding an intelligent GUI for your C/C++ code. 可能你应该尝试为你的C / C ++代码找到一个智能的GUI。

Because the second you trust the computer to think for you, you've got a major case of SkyNet on your hands. 因为第二个你信任计算机为你思考 ,你手上有一个重大的SkyNet案例。

Computers, in general, are very bad at making choices, except for very simple ones. 一般而言,计算机在做出选择时非常糟糕,除非是非常简单的。 Pulling something out of dependency hell simply isn't a task you should entrust it with, because that kind of thinking leads to sloppy coding and buggy code. 从依赖地狱中拉出一些东西根本不是你应该委托给它的任务,因为那种思维导致了草率的编码和错误的代码。

If I reference a function named sqrt , how does the compiler know which file to look in, if I haven't specified it? 如果我引用一个名为sqrt的函数,编译器如何知道要查找哪个文件,如果我没有指定它? It could be absolutely any file on my entire harddrive. 它可能绝对是我整个硬盘上的任何文件。

Unlike Java, C++ doesn't really consider any files "special". 与Java不同,C ++并不真正认为任何文件“特殊”。 Java has its giant (bloated) class library, which is automatically made accessible to the programmer. Java有它的巨型(臃肿)类库,程序员可以自动访问它。

In C++, this concept doesn't exist. 在C ++中,这个概念不存在。 You tell the compiler which paths to search in, and whenever you #include a file, it will search for the filename in those paths. 您告诉编译器要搜索哪些路径,每当#include文件时,它将在这些路径中搜索文件名。

If that happens to find a standard library file, it'll use that. 如果碰巧找到标准库文件,它将使用它。 If it happens to find a third-party file, it'll use that. 如果碰巧找到第三方文件,它会使用它。

The compiler doesn't know that sqrt is defined in the header math.h . 编译器不知道math.h定义了sqrt Or that it is also typically defined in cmath In fact, the functions defined by a header might vary . 或者,它通常限定cmath实际上,通过一个报头中定义的功能可能会有所不同 Perhaps, if I #define the appropriate preprocessor symbol, some functions will be removed from a specific header, and others will be enabled. 也许,如果我#define适当的预处理器符号,一些函数将从特定的标题中删除,其他函数将被启用。

But unlike Java, where the functions and classes defined by a library can be determined just by examining the library file's metadata, in C++, the header has to be compiled. 但是与Java不同,Java只能通过检查库文件的元数据来确定库定义的函数和类,而在C ++中,必须编译头文件。 And the result of compiling it might vary depending on the context in which it is included. 编译它的结果可能会有所不同,具体取决于包含它的上下文。

So the C++ compiler cannot guess at which header should be included in order to define the function you just used. 因此,C ++编译器无法猜测应该包含哪个头,以便定义您刚刚使用的函数。

The compiler shouldn't have to think for you. 编译器不应该为你考虑。 What if there is a function of the same name in two different libraries? 如果两个不同的库中有相同名称的功能怎么办? How would it know which header to include and which library to link against? 如何知道要包含哪个标头以及要链接哪个库? Having a compiler or IDE silently fixing your sloppy code is a bad idea in my opinion. 在我看来,让编译器或IDE默默地修复你的草率代码是一个坏主意。

Part of the difference is because of a few fundamental design decisions that were made differently between the two. 部分差异是由于一些基本设计决策在两者之间做出了不同的决定。 In particular, Java requires that the name of a class match the name of the file, so the name of the class you use pretty much tells it what you needed to import. 特别是,Java要求类的名称与文件名匹配,因此您使用的类的名称几乎告诉它您需要导入的内容。

In C or C++, the name you give to a header doesn't necessarily have to match the contents at all. 在C或C ++中,您为标题指定的名称不一定必须与内容匹配。 If you wanted to badly enough, you could name your headers 1.h, 2.h, 3.h, and so on -- or even 1.bas, 2.pas, 3.java, 4.ada, and whatever other misleading names you happen to prefer. 如果你想要足够严重,你可以命名你的标题1.h,2.h,3.h等等 - 甚至1.bas,2.pas,3.java,4.ada等等你喜欢的误导性名字。 That's obviously a poor idea, but if you did it anyway, the compiler wouldn't be at all bothered. 这显然是一个糟糕的主意,但如果你这样做了,编译器就不会受到打扰。

As such, it's much more difficult for a C or C++ tool to guess at what header needs to be included to get the definition of a particular type. 因此,C或C ++工具更难以猜测需要包含哪个头来获取特定类型的定义。 In theory, it could (for example) build a big database of all the functions, classes, types, etc., in all the headers you've written, and when you use one, tell you which header(s) define what names, but I'm not aware of an IDE that actually does so. 从理论上讲,它可以(例如)在你编写的所有头文件中构建一个包含所有函数,类,类型等的大数据库,当你使用它时,告诉你哪个头定义了什么名称,但我不知道IDE实际上是这样做的。

NetBeans is an IDE (Integrated Development Environment). NetBeans是一个IDE(集成开发环境)。 Some C/C++ IDEs do have that feature...but not everybody knows about it or utilizes it. 有些C / C ++ IDE确实有这个功能......但不是每个人都知道它或利用它。

Because in general it's a difficult problem to know which header files you need to include to define something properly. 因为一般来说,知道需要包含哪些头文件来正确定义内容是一个难题。 It would be quite a nice feature to have your IDE be able to guess simple cases and offer to help though. 让你的IDE能够猜出简单的案例并提供帮助是一个非常好的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM