10

我使用cnPack 使用清洁器,但总的来说,拥有无用单元的缺点是什么?

我知道其中一些:

1)当然,如果整个项目中从未使用过该单元,则会消耗无用的资源

2)代码洞察力将给出无用的结果

3)代码洞察会变慢

但是想象一个简单的例子:

  • 我有一个有 2 种形式的项目,我在其中一种形式中使用 StrUtils,但我在两种形式中都声明了 StrUtils ......在这种情况下,内存消耗是否有任何不利因素?
4

3 回答 3

16

不。一般来说,智能链接的工作原理是这样的:

  • 如果您在某处使用单元,则至少链接了初始化和完成代码。
  • 原则上,只有您实际使用的函数/方法,直接或间接从主程序(.dpr) 链接。
  • 一些可通过RTTI访问的位也将被链接。经验法则是枚举的 RTTI 总是被链接(如果你使用枚举),并且(一旦你构造一个类),所有发布的或可达的通过已发布的属性链接。
  • 请记住,未使用单元的初始化可能会引入dll甚至整个 dll 框架(如 .NET),这可能是不必要的部署复杂化。
  • (正如 Rob 在评论中所说)资源是另一个始终链接的因素,因为由于它们的运行时使用,编译器无法确定它们是否被使用。
  • 在 DLL 或包项目中,所有已发布的符号都将被链接,因为外部程序可能会调用它们。

结论:最终.exe大小确定

  • 主要是通过以上根可以到达的任何东西(主程序,初始化,终结,可以构造的类的 RTTI),
  • 如果单元被使用(资源,某些形式的 RTTI,如枚举),则始终链接的一些位,
  • RTL 中的语言助手,如 ansistring 助手例程,其中大部分在 System 中,有些可能在变体中。
  • 一些相对较小的内部程序管理(例如,具有确定初始化/完成顺序的单元的表)、资源处理所需的表、DLL 链接等。
  • 调试信息(如果 TD32 开启)
  • 优化和运行时检查等编译器设置也会轻微影响二进制文件大小。
  • 像 UPX 这样的二进制压缩工具。不过我不推荐这些,因为根据我的经验,它们经常会引起问题。

Free Pascal 的工作方式大致相同,只是默认值不同;调试目前几乎总是“二进制”(如 TD32),并且在快照中,智能链接默认关闭。(虽然在官方版本中它是开启的)。

此外,我们绝不能忽视规模。整个 Strutils 最大为 15kb。

(2011-11-01更新)

有人对我喜欢分享的这个回复发表了评论:

基本上他对枚举总是链接的评论表示怀疑。也许注册具有枚举类型的已发布属性的类会将它们拖进来。推理是有道理的,但我还没有测试过。因此,只有在某处查询 typeinfo(tenumtype) 或者在使用的类的已发布部分中使用它时,才能直接链接 enum 的 RTTI。(直接或查询typeinfo(theclass))

于 2010-12-23T15:02:25.350 回答
7

Delphi 智能链接器将忽略未使用的代码,因此通常这些“额外”单元的存在不会增加已编译程序的大小。

以下是我从这个链接中得到的关于未使用单位的缺点的一些观点

  1. 维护更清洁的代码,无需担心未使用的代码
  2. 未使用单元中初始化和终结部分的代码未链接到
  3. 编译运行更流畅、更快
于 2010-12-23T15:01:28.507 回答
6

在我看来,最大的问题是你有时会被 Delphi 范围规则所吸引。如果你在不同的单元中有两个同名的标识符,那么使用这个名称是指在uses 子句中最近声明的单元中声明的那个。

如果您因此遇到问题,您始终可以完全指定标识符。我真正希望看到的是编译器警告,告诉您是否正在命名一个标识符,该标识符的身份仅由使用子句范围规则中的最新声明确定。

于 2010-12-23T16:45:48.267 回答