题
任何建议做法清理"标题的意大利面"这是引起极 慢汇编时(Linux/Unix)?
是否有任何equvalent为"#pragma一次"与海湾合作委员会?
(找到相互矛盾的信息,关于这个)
谢谢。
解决方案
假设你熟悉“包含守卫”。 (#ifdef在标题的开头......),另一种加速构建时间的方法是使用外部包含警卫。 在“大规模C ++软件设计中讨论过它&QUOT ;.这个想法是经典包括守卫,不像#pragma一次,不要让你从第二次开始忽略头部所需的预处理器解析(即它仍然需要解析并寻找包含守卫的开始和结束。外部包括警卫你将#ifdef放在#include线本身周围。
所以它看起来像这样:
#ifndef MY_HEADER
#include "myheader.h"
#endif
当然在H档案中你有经典的包含守卫
#ifndef MY_HEADER
#define MY_HEADER
// content of header
#endif
这样,myheader.h文件甚至不被预处理器打开/解析,它可以在大型项目中节省大量时间,特别是当头文件位于共享远程位置时,就像它们有时一样。 / p>
再次,这一切都在那本书中。 HTH
其他提示
如果你想做一个完整的清理并有时间去做,那么最好的解决办法是删除所有文件中的所有#includes(除了显而易见的,例如abc.cpp中的abc.h)然后编译该项目。添加必要的前向声明或标题以修复第一个错误,然后重复,直到你干净利落。
这不会解决可能导致包含问题的潜在问题,但它确实确保只包含必需的问题。
我读了关于一个整洁的骗降低头依赖关系:编写脚本,这将
- 找到所有#包括报表
- 除一个发言的时间,并重新编译
- 如果编制的失败,加上包括发言回来
最后,你会希望结束与最低的要求包括在代码。你可以写一个类似的脚本,重新安排包括找出如果他们是自给自足,或者需要其他的头被包括在他们之前(包括该标题第一,如果编制的失败,报告)。应该去一些方法来清理你的代码。
一些更多的注意事项:
- 现代化的汇编者(海湾合作委员会在他们之中)认识到头警卫,并优化在相同的方式说明一旦会,只有打开文件的一次。
pragma一旦可能会出现问题时的同样的文件有不同的名称在该文件系统(即与软联)
- 海湾合作委员会支持#pragma一次,但称它"过时"
pragma一次不支持由所有编译器,而不是部分C的标准
- 不只编译可能会有问题。工具,如额外的资料中了解更多,也有问题#pragma一次
理查德有点不对(为什么他的解决方案被记下来?)。
无论如何,所有C / C ++标题都应该使用内部包含保护。
这就是说:
1 - 你的遗留代码不再被维护了,你应该使用预编译的头文件(这是一个黑客,但是嘿......你需要加快编译速度,而不是重构非维护代码)
2 - 您的遗留代码仍然存在。然后,您可以使用预编译的头文件和/或警卫/外部警卫来获得临时解决方案,但最后,您需要一次删除所有包含,一个.C或.CPP,然后编译每个包含。 C或.CPP文件一次一个,使用前向声明更正其包含或在必要时包括(或者甚至将大型包含分成较小的包含以确保每个.C或.CPP文件仅获得所需的标头)。无论如何,测试和删除过时的包含是项目维护的一部分,所以......
我对预编译头文件的经验并不是很好,因为有一半时间,编译器找不到我定义的符号,所以我尝试了一个完整的“清理/重建”,以确保它是不是过时的预编译头。所以我的猜测是将它用于你甚至不会触摸的外部库(比如STL,C API头,Boost等)。不过,我自己的经验是使用Visual C ++ 6,所以我猜(希望?)他们现在做对了。
现在,最后一件事:标题应始终是自给自足的。这意味着如果包含标题取决于包含顺序,那么您就有问题了。例如,如果你可以写:
#include "AAA.hpp"
#include "BBB.hpp"
但不是:
#include "BBB.hpp"
#include "AAA.hpp"
因为BBB依赖于AAA,所以你所拥有的只是一个你从未在代码中承认的依赖。不用定义来确认它只会让你的编辑成为一场噩梦。 BBB也应该包括AAA(即使它可能稍慢一些:最终,前向声明无论如何都会包含干净无用的内容,所以你应该有一个更快的编译计时器。)
使用其中一个或多个来加快构建时间
- 使用预编译标题
- 使用缓存机制(例如scons)
- 使用分布式构建系统(distcc,Incredibuild($)) 醇>
在标题中:仅当您不能使用前向声明时才包含标题,但始终#include您需要的任何文件(包括依赖项是邪恶的!)。
正如在另一个答案中所提到的,你应该尽可能使用前向声明。据我所知,GCC没有任何等同于#pragma的东西,这就是为什么我坚持使用包含守卫的旧时尚风格。
感谢您的回复,但问题是关于现有代码,其中包括严格的“包含订单”。等等 问题是,是否有任何工具/脚本来澄清实际情况。
Header guard不是解决方案,因为它们不会阻止编译器一次又一次地读取整个文件......
PC-Lint 将大大有助于清理意大利面条标题。它也会为你解决其他问题,比如未初始化的变量,看不见等等。
作为onebyone.livejournal.com 在评论一个响应你的问题,一些支助编译器 包括警卫队优化, ,第I页链接的定义如下:
包括警卫队优化是当一个编译器承认内部包括卫队成语上所述,并采取步骤,以避免打开文件多次。编译器可以看看一个包括文件、条出的评论和空白空间和工作,如果整个文件是在包括警卫。如果是,它储存的文件,包括保护状况的地图。下次编译器的要求包括文件,它可以检查包括保护条件和作出的决定是否跳过的文件或#包括它不需要公开的文件。
再说,你已经回答说,包括外部警卫是不是回答你的问题。为解开头的文件必须包含在一个特定的顺序,我会建议如下:
- 每
.c
或.cpp
文件应该#include
相应的.h
文件第一和其余的#include
指令,应该按字母顺序排序。你通常会得到建立的错误,当这打破未说明的依赖之间的头文件。 - 如果你有一头文件,该文件界定了全球typedef基本类型或全球的
#define
指令中使用的大多数代码,每.h
文件应该#include
该文件第一和其余的#include
指令,应该按字母顺序排序。 - 当这些变化导致编译的错误,你通常必须添加一个明确的依赖从一个标题的文件,另一个形式
#include
. - 当这些变化不会引起编译错误,他们可能会导致行为的改变。希望你有某种测试,可用于验证功能的应用程序。
它还听起来像一部分的问题可能是递增的基础是慢得多的比他们应该是。这种情况可以改善与前声明或一个分布式建立系统,正如其他人已经指出。