【问题标题】:How to give a warning if h file is not included directly如果不直接包含 h 文件如何发出警告
【发布时间】:2016-12-13 00:57:09
【问题描述】:

假设我有几个“h”文件:

First.h

struct FirstStruct { /* Stuff */ };
/* Other stuff */

第二个.h

#include "First.h"
struct SecondStruct { 
  FirstStruct member; 
  /* More other stuff */ 
};
/* Even more other stuff */

第三个.h:

#include "Second.h"

FirstStruct foo(void);
/* Other functions */

如果您注意到Third.h 没有直接获得FirstStruct 的定义(即从包含First.h),而是因为Second.h 包含它。问题是,当开发人员决定 SecondStruct 并不真正需要 FirstStruct 时,它需要半等效结构 OtherStruct,然后将 include 取出到 First.h ......现在糟糕了任何使用Third.h 的东西都不起作用。

如果您依赖其他 h 文件包含,是否有任何半标准编译器选项来警告您?

【问题讨论】:

  • (a) 搜索 IWYU — 包括您使用的内容。 (b) 当您进行更改时,应该有一个发现编译问题的测试。没有简单的解决方法。
  • 编译器无论如何都会“爆炸”......因为如果没有正确的#include,将无法找到Third.h 中的FirstStruct 声明。多个#include <...> 对适当的警卫来说从来都不是问题。
  • @WhiZTiM 它只会在开发者没有将它包含在 Second.h 中时才会爆炸,如果我给它我现在拥有的它甚至不会退缩
  • 如果有人故意更改 Second.h,他们不应该负责确保他们没有破坏构建吗?如果您的开发人员会定期提交对头文件的更改而不检查他们是否破坏了构建,那么您需要寻找新的开发人员。
  • @Peter 真正的问题是当 h 文件被深埋很多层时,开发人员对它为什么不编译感到非常困惑(显然他可以通过一些工作弄清楚)。但真正的问题是我们依赖的事实包括

标签: c++ c include warnings


【解决方案1】:

如果你有标头保护,并且文件 "First.h" 的标头保护是 FIRST_HEADER_H,你可以这样做

#ifndef FIRST_HEADER_H
/*warning*/
#pragma message("FREE ADVICE: You should include The file: First.h")
#endif

主要编译器supportthis.

另外我认为你应该阅读self contained headers,它说任何使用first.h在这个例子中)的文件都应该包括first.h,所以third.h应该可能改为阅读:

#include "First.h"
#include "Second.h"

FirstStruct foo(void);
/* Other functions */

【讨论】:

  • 奇怪...但它会起作用...为了清楚起见,您可以将答案修改为 workable 状态吗?我的意思是,添加潜在的工作代码
  • @WhiZTiM 我不认为我真的理解这是如何工作的......如果我包含 Second.h (并添加标题保护)FIRST_HEADER_H 仍然会被定义(因为它是当您包含 Second.h 时定义).....所以这行不通(我认为)
  • 你知道什么是头守卫吗?如果没有,请阅读有关它们的信息。如果您的 first.h 有一个标头保护,例如FIRST_HEADER_H,您可以检查它是否已定义,如上。如果不是,则不包括first.h,无论是直接还是间接。
  • @WhiZTiM 我已经更新了我的问题.....我认为我的要求可能更清楚一点......我认为你误会了我的要求.....可能主要是因为我实际上并没有直接出来问问题
  • 虽然技术上正确,但正确的解决方案是首先包含标题。
【解决方案2】:

您通过发现您的程序不再编译来检测这种情况。

然后您将#include "First.h" 添加到Third.h 中(正如您一开始就应该做的那样——是的,即使您也包括Second.h)并解决您的问题跟踪系统上的错误。

没有可以打开的编译器警告表明这一问题可能有一天会发生。 C++ 编译器非常希望某些符号只能通过标题间接获得;即使在您自己的代码中故意这样做是一种不好的做法,但如果您使用任何库(包括标准库),这样的警告会使编译变得非常嘈杂。

因此,您可以采取的唯一先发制人的步骤是在您的同行中仔细审查代码,以及允许有时间修复意外错误的项目管理结构。

诚然,这有点烦人。

【讨论】:

  • 我希望找到一种方法来抢先解决可能的问题
  • @DarthRubik:同行评审? :)
  • 可能应该这样说“我希望编译器切换、第 3 方工具、宏 hack 或任何其他自动化过程来抢先解决可能的问题”
  • @DarthRubik:是的,我明白了。请参阅我的扩展答案。
猜你喜欢
  • 2012-09-27
  • 2016-10-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2013-04-15
  • 2013-02-21
  • 2013-04-13
相关资源
最近更新 更多