我知道存在一些“临时”的 LaTeX 尺寸等。但是,我希望了解所有这些尺寸。
我知道\reserved@a
(宏观)、\@tempdima
(维度)和\@tempcnta
(反面)。
答案1
TeX/LaTeX 中临时寄存器和宏的使用可以追溯到节省内存消耗绝对必要的时代,因为 TeX 的内存(包括标记/宏内存以及可用寄存器的数量)非常有限,并且仅在主格式上加载几个包就很容易耗尽空间。
这种痕迹在代码中随处可见,例如,您会看到像\@plus
这样的内容是 5 个标记的缩写plus
,因此每次在代码中需要它时,您都会节省 4 个标记。对于寄存器也是如此,每个类型的总数限制为 256 个,并且加载,例如pictex
已经可以接近可用计数和维度寄存器的总限制。
但是,使用临时寄存器和宏来克服这些限制总是要付出代价的:总是存在寄存器或宏被重用的危险,而您的代码仍然假设它保存着您的值!尽管采取了很多预防措施(例如仅在组中使用它们,或确保设置和使用确实彼此相邻),但它一次又一次地导致了错误和问题,因为宏在其他参数中被调用(两者都假设它们可以安全地使用相同的临时对象)或者由于在意外情况下访问输出例程会改变上下文。
随着 1994 年左右诞生的 LaTeX2e 的大小限制变得更加严重,因为核心代码得到了扩展。所以我们不得不在各处使用临时寄存器,并尽可能节省内存。但我们知道这些问题,所以我们将临时寄存器分成两部分:一部分是我们希望只在内核代码中使用的,另一部分是过去已经被第三方软件包使用过的(如果不破坏这些软件包,我们就无法删除它们)。因此,我们引入了临时寄存器,\reserved@...
希望名称清楚地表明它们是不是旨在供软件包作者使用。
底线:使用临时寄存器和宏是不是除非有非常好的理由,并且如今原始原因(内存限制)不再有效,否则不建议这样做。如今所有现代 TeX 安装(不到十年左右)都是基于 eTeX 的,并且都提供了足够的空间和寄存器,因此如果软件包使用自己的私有命令和寄存器,则可以更方便、更简单,因此可以放心地并行使用而不会出现任何问题。
使用 LaTeX3 ( expl3
) 我们建议根本不使用任何临时寄存器尽管我们确实提供了一些,但我们知道旧习惯不会轻易消失。
答案2
LaTeX 内核分配了一些暂存寄存器并定义了暂存条件。完整列表如下
\newcount\@tempcnta
\newcount\@tempcntb
\newif\if@tempswa
\newdimen\@tempdima
\newdimen\@tempdimb
\newdimen\@tempdimc
\newbox\@tempboxa
\newskip\@tempskipa
\newskip\@tempskipb
\newtoks\@temptokena
请注意,前两个\newcount
使用的是,而不是\newcounter
。所有这些寄存器和\if@tempswa
(以及伴随宏\@tempswatrue
和\@tempswafalse
)必须仅在本地使用,因此绝不用前缀分配值\global
。
寄存器分配机制总是留下前十个寄存器号,因此
\dimen0 ... \dimen9
\skip0 ... \skip9
\toks0 ... \toks9
并且盒子寄存器 0 到 9 可自由用于暂存。一个公认的惯例(不幸的是,有些软件包不遵循)是偶数暂存寄存器应在本地使用,奇数暂存寄存器应在全局使用。对于本地使用,还有
\count@
\dimen255
\skip255
\toks255
但不是box寄存器255;\count@
是的别名\count255
,实际上,而\dimen@
、\skip@
和\toks@
代表每种类型的0寄存器。
内核也使用\reserved@a
、、和作为临时\reserved@b
宏,但除了特殊任务外,它最好\reserved@c
\reserved@d
\reserved@e
不是在包或个人宏中使用它们。该宏\@gtempa
用作“全局临时宏”,其含义应始终全局设置。
寄存器也\muskip0
可以\muskip9
用作临时寄存器,但我不知道有任何软件包使用它们。
临时条件和寄存器的使用应该遵循一些简单的规则。
在使用它们之前永远不要依赖它们的值,因此在作业开始时初始化它们的值。
当您需要这些寄存器具有可依赖的值时,请避免调用可能使用相同临时寄存器的宏,除非在组内进行调用,以便在组末恢复先前的值。
如有疑问,不使用临时寄存器,但分配您自己的寄存器。
任何寄存器可以用作临时寄存器,前提是这是在组内完成的,并且遵循上述规则(但要更加注意可能的值破坏)。因此,在组内找到\count0
并用作临时寄存器是相当常见的;这是安全的,前提是没有执行任何可以触发分页的操作。为什么?计数器的\count2
值在操作期间记录在 DVI 或 PDF 输出中(如果非零,则为编号为 1 到 9 的寄存器);LaTeX 计数器实际上是。\count0
\count9
\shipout
page
\count0
一个非常常见的陷阱是使用盒子寄存器时做遵循组结构,其特点是\box
并\unhbox
破坏框寄存器的当前化身。因此,之后
\setbox0=\hbox{foo}\begingroup\box0\endgroup
框寄存器 0 将无效。另一方面,
\setbox0=\hbox{foo}\begingroup\setbox0=\hbox{bar}\box0\endgroup
将导致盒子寄存器 0 仍然包含\hbox{foo}
。
答案3
这可能只是部分答案,取决于您对可能也定义临时寄存器/变量的其他包的看法。
搜索latex.ltx
你会发现一些临时的东西(实际上定义在ltalloc.dtx
):
\newcount\@tempcnta
\newcount\@tempcntb
\newdimen\@tempdima
\newdimen\@tempdimb
\newdimen\@tempdimc
\newbox\@tempboxa
\newskip\@tempskipa
\newskip\@tempskipb
\newtoks\@temptokena
还有,但正如约瑟夫所评论的,\newif\if@tempswa
这与属于同一范畴。\@reserved@...