多次使用 headers 不好吗?

Is using headers multiple times bad?

假设我正在使用 header 守卫,

#ifndef MAIN_H
#define MAIN_H

#include "foo.h"
#include "some_header_file.h"

... // Some Code

#endif   

内部 foo.h 文件也有 Header 守卫。

#ifndef FOO_H
#define FOO_H

#include "some_header_file.h"
... // Some Code

#endif   

如您所见,主文件有 2 个 header,其中一个是重复的。我有三个问题:

  1. Header 守卫是否防止重复 header 文件?
  2. 编译器是否优化并删除了它?
  3. 这是一种不好的做法吗,额外的 header 文件应该从主文件中删除吗?

Does Header guards prevent duplicate header files?

是的。第一个遇到的包含会将 header 的内容带到翻译单元,并且 header 守卫会导致连续的包含为空,从而防止 header 的内容被复制。这正是使用 header 守卫的原因。

or is this a bad practice and the extra header file should be deleted from main file?

不,重复包含不是一个坏习惯。如果“main”header 依赖于“some_header_file.h”的任何声明,那么“main”绝对应该直接包含“some_header_file.h”,无论是另一个 header - 即使包含一个by "main" - 也包括或不包括它。

依赖传递包含通常是一种不好的做法——即在这种情况下,依赖“foo.h”包含“some_header_file.h”的细节可能是不好的,而包含“foo.h”到“主要”。此类假设通常会导致程序在修改时意外中断。在这种情况下,如果“foo.h”被修改为不再依赖于“some_header_file.h”,并且该包含被删除,那么该更改会突然导致假设失败,并且“some_header_file.h”将不再包含在“main”中,因为根本不涉及“main”的更改。那可就糟了。

repited include 的主要问题是当两个不同的文件相互包含时。例如,如果 a.h 包含 b.h,而 b.h 包含 a.h,如果你不添加 header guards,预处理器最终会进入一个循环,因为每次读取a.h 包括 b.h,b.h 包括 a.h,这永远不会结束。

在你的情况下,如果你在 some_header_file.h" 中定义一个变量,你可能会遇到一些问题,因为它会被读取两次并且变量也会被声明两次,这会导致编译器错误。

您需要将它们添加到“some_header_file.h”中,这样​​下次预处理器读取此文件时,它会通过 ifndef 子句忽略它。并注意循环包含依赖项的重要性。

在“some_header_file.h”中添加:

#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
...code
#endif /* SOME_HEADER_FILE_H */

最后一条评论不是必需的,但它有助于您需要 debug/review 预处理器输出的情况。