繁体   English   中英

包含在头文件中

Includes within header files

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

头文件应该#include s吗?

我一般认为这种等级包含是坏的。 说你有这个:

foo.h中:

#include <stdio.h> // we use something from this library here
struct foo { ... } foo;

main.c中

#include "foo.h"
/* use foo for something */
printf(...)

当main.c的实现发生变化,并且您不再使用foo.h时,编译将中断,您必须手动添加<stdio.h>

与此有关:

foo.h中

// Warning! we depend on stdio.h
struct foo {...

main.c中

#include <stdio.h> //required for foo.h, also for other stuff
#include "foo.h"

当你停止使用foo时,删除它不会破坏任何东西,但是删除stdio.h会破坏foo.h.

应该从.h文件中禁止#includes吗?

6 个回复

你已经概述了关于这个主题的两个主要哲学。

我自己的观点(我认为这就是人们真正拥有的所有观点)是标题应尽可能自包含。 我不想知道foo.h所有依赖关系只是为了能够使用该头。 我也鄙视必须按特定顺序包含标题。

但是, foo.h的开发人员也应该负责使其尽可能无依赖。 例如,如果可能的话,应该编写foo.h头文件,使其不依赖于stdio.h (使用前向声明可以帮助解决这个问题)。

请注意,C标准禁止标准标题包含另一个标准标题,但C ++标准不允许。 因此,您可以看到从一个C ++编译器版本转移到另一个C ++编译器版本时所描述的问题 例如,在MSVC中,包括<vector>用于引入<iterator> ,但在MSVC 2010中不再出现,因此之前编译的代码可能不再存在,因为您可能需要专门包含<iterator>

但是,即使C标准似乎提倡第二种哲学,但请注意,它还要求没有标题依赖于另一种标题,并且您可以按任何顺序包含标题。 因此,您可以充分利用这两个领域,但代价是C库实施者的复杂性。 他们必须跳过一些箍来做这件事(特别是支持可以通过几个头中的任何一个引入的定义,比如NULLsize_t )。 我想那些起草C ++标准的人决定将这种复杂性添加到模仿者不再合理(我不知道C ++库实现者在多大程度上利用了'漏洞' - 看起来MS可能会收紧这个问题,即使它在技术上不是必需的)。

我的一般建议是:

  • 一个文件应该#include它需要的东西。
  • 它不应该期望别的东西#include它需要的东西。
  • 它不应该#include它不需要的东西,因为其他东西可能想要它。

真正的测试是这样的:您应该能够编译包含任何单个#include的源文件,并且除了“没有main() ”之外不会得到任何错误或警告。 如果你通过了这个测试,那么你可以期待任何其他能够#include你的文件没有问题。 我写了一个名为“hcheck”的简短脚本,用于测试:

#!/usr/bin/env bash
# hcheck: Check header file syntax (works on source files, too...)
if [ $# -eq 0 ]; then
    echo "Usage: $0 <filename>"
    exit 1
fi

for f in "$@" ; do
    case $f in
        *.c | *.cpp | *.cc | *.h | *.hh | *.hpp )
            echo "#include \"$f\"" > hcheck.cc
            printf "\n\033[4mChecking $f\033[0m\n"
            make -s $hcheck.o
            rm -f hcheck.o hcheck.cc
            ;;
    esac
done

我确信这个脚本可以做得更好,但它应该是一个很好的起点。

如果这太多了,如果你的头文件几乎总是有相应的源文件,那么另一种技术是要求相关的头是源文件中的第一个#include 例如:

foo.h中:

#ifndef Foo_h
#define Foo_h

/* #includes that Foo.h needs go here. */

/* Other header declarations here */

#endif

foo.c的:

#include "Foo.h"
/* other #includes that Foo.c needs go here. */

/* source code here */

这也显示了其他人提到的Foo.h中的“包括警卫”。

首先将#include "Foo.h"放在#include "Foo.h"Foo.h必须#include其依赖项,否则你将遇到编译错误。

好吧,主要不应该首先依赖"foo.h"来获得stdio 包括两次东西没有坏处。
也许,也许foo。 h真的不需要stdio 更有可能的是foo.c (实现)需要stdio

长话短说,我认为每个人都应该包括他们需要的东西,并依赖包括警卫

一旦进入包含数百或数千个头文件的项目,这就变得难以理解了。 假设我有一个名为"MyCoolFunction.h"的头文件,其中包含MyCoolFunction()的原型,该函数将结构指针作为参数。 我应该能够假设包含MyCoolFunction.h将包含所有必要的内容并允许我使用该函数而无需查看.h文件以查看我需要包含的其他内容。

如果头文件需要特定标头,请将其添加到头文件中

#ifndef HEADER_GUARD_YOUR_STYLE
#define HEADER_GUARD_YOUR_STYLE

#include <stdio.h> /* FILE */
int foo(FILE *);

#endif /* HEADER GUARD */

如果代码文件不需要标头,请不要添加它

/* #include <stdio.h> */ /* removed because unneeded */
#include <stddef.h> /* NULL */
#include "header.h"
int main(void) {
  foo(NULL);
  return 0;
}

为什么不#include与标题对应的* .c文件中的东西?

2 头文件包含在纯虚拟类中

如果我有一个像下面这样的纯虚拟类: 我有如下的类结构: 包含MyClassA / MyClassB的正确方法是什么? 我应该在接口类的头文件中进行一些前向声明,并将其真正包含在实现的头文件中,还是应该直接在接口类中包括MyClassA / B的头文件? ...

2012-02-15 09:17:12 2 134   c++
3 导入并包含在头文件中-什么时候可以?

我读过规则是不要#import或#include .h文件中的任何内容。 真的吗? 就在今天,我遇到了两次不得不做的单独的场合,一次是导入包含typedef enum的头文件,因为我的方法存根使用它作为参数,另一次是我必须导入头文件来声明委托。 这些情况的实际规则是什么? 有时可 ...

4 C 头文件包含在另一个头文件中并且都包含在 ac 文件中

我有一个关于 C 中的头文件的问题。假设我有一个头文件,其中包含一个名为cars.h的结构cars.h ,如下所示: 现在,我有另一个头文件,其中包含上述头文件,称为drivers.h ,如下所示: 现在,假设我有另一个文件,但这次它是一个 C 文件,名为main.c ,如下所示: 你能 ...

6 头文件应包含在.h或.m文件中吗?

如果我有四个.h / .m文件对 file1.h file2.h file3.h file4.h 我在file4中使用file1.h,file2.h和file3.h功能的地方,那些头文件应该包含在file4.h或file4.m中吗? ...

2011-04-21 19:20:40 3 527   xcode/ ios
8 头文件可以包含在多个源文件中,而没有重复保护

大多数头文件将其内容包装为: 如果将其删除,则将头文件包含在多个源文件中时是否会引起问题? 还是预处理器足够聪明,可以忽略它? (我知道在同一源文件中多次包含它时会引起问题) ...

2019-02-19 01:55:33 3 63   c++/ c
9 为什么头文件需要包含在定义文件中?

我是 C 新手,只是一个关于头文件的问题,下面是推荐使用头文件的代码: 我不明白为什么我们需要将#include "test.h"放在test.c文件中,这样做有什么好处? ...

2020-08-25 00:19:50 1 39   c/ gcc
10 使用头文件而不包含在源文件中

我将现有的borland c ++源代码移植到gcc Compatible中。 我正在使用make来编译源代码。 在borland源文件中的一个文件中,他使用的是来自不同头文件的定义,而没有将该头文件包括在特定的.h文件中。 当我尝试编译相同文件时,出现错误,提示未定义。 那么我们如何才 ...

暂无
暂无

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

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