Skip to main content
minor formatting
Source Link
percusse
  • 159.7k
  • 15
  • 344
  • 577

The LaTeX kernel allocates some scratch registers and defines a scratch conditional. The complete list is

\newcount\@tempcnta \newcount\@tempcntb \newif\if@tempswa \newdimen\@tempdima \newdimen\@tempdimb \newdimen\@tempdimc \newbox\@tempboxa \newskip\@tempskipa \newskip\@tempskipb \newtoks\@temptokena 

Notice that for the first two \newcount is used, rather than \newcounter. All these registers and \if@tempswa (with the companion macros \@tempswatrue and \@tempswafalse) must be used only locally, so *never* assigned values with the \global`) must be used only locally, so never assigned values with the \global prefix.

The register allocation mechanism always leaves free the first ten register numbers, so also

\dimen0 ... \dimen9 \skip0 ... \skip9 \toks0 ... \toks9 

and box registers 0 to 9 are free for scratch usage. An agreed upon convention (that unfortunately some packages don't follow) is that even numbered scratch registers should be used locally, and odd numbered ones should be used globally. Also for local usage are

\count@ \dimen255 \skip255 \toks255 

but not box register 255; \count@ is an alias for \count255, actually, while \dimen@, \skip@ and \toks@ stand for the 0 register of each type.

The kernel uses also \reserved@a, \reserved@b, \reserved@c, \reserved@d and \reserved@e as scratch macros, but apart from special tasks, it's better not using them in packages or personal macros. The macro \@gtempa is used as "global scratch macro" and its meaning should always be set globally.

Also registers \muskip0 to \muskip9 are available as scratch registers, but I don't know of any packages that uses them.

Usage of scratch conditional and registers should follow some simple rules.

  1. Never rely on their value before using them, therefore initialize their value at the start of the job.

  2. Avoid calling macros that might use the same scratch registers during the time you need those register to have a relied upon value, unless the call is made inside a group, so that the previous value will be restored at group end.

  3. In case of doubt, don't use scratch registers, but allocate your own.

Any register can be used as scratch register, provided this is done inside a group and following the rules above (but with more care about possible value clobbering). So it's fairly common to find \count0 and \count2 used as scratch registers inside a group; this is safe, provided nothing that can trigger a page break is performed. Why? The value of the counters \count0 to \count9 is recorded in the DVI or PDF output during a \shipout operation (if nonzero, for the registers numbered 1 to 9); the LaTeX counter page is actually \count0.


A very common pitfall is in the usage of box registers which do follow the group structure, with the peculiarity that \box and \unhbox destroy the current incarnation of the box register. So, after

\setbox0=\hbox{foo}\begingroup\box0\endgroup 

the box register 0 will be void. On the other hand,

\setbox0=\hbox{foo}\begingroup\setbox0=\hbox{bar}\box0\endgroup 

will result in box register 0 still containing \hbox{foo}.

The LaTeX kernel allocates some scratch registers and defines a scratch conditional. The complete list is

\newcount\@tempcnta \newcount\@tempcntb \newif\if@tempswa \newdimen\@tempdima \newdimen\@tempdimb \newdimen\@tempdimc \newbox\@tempboxa \newskip\@tempskipa \newskip\@tempskipb \newtoks\@temptokena 

Notice that for the first two \newcount is used, rather than \newcounter. All these registers and \if@tempswa (with the companion macros \@tempswatrue and \@tempswafalse) must be used only locally, so *never* assigned values with the \global` prefix.

The register allocation mechanism always leaves free the first ten register numbers, so also

\dimen0 ... \dimen9 \skip0 ... \skip9 \toks0 ... \toks9 

and box registers 0 to 9 are free for scratch usage. An agreed upon convention (that unfortunately some packages don't follow) is that even numbered scratch registers should be used locally, and odd numbered ones should be used globally. Also for local usage are

\count@ \dimen255 \skip255 \toks255 

but not box register 255; \count@ is an alias for \count255, actually, while \dimen@, \skip@ and \toks@ stand for the 0 register of each type.

The kernel uses also \reserved@a, \reserved@b, \reserved@c, \reserved@d and \reserved@e as scratch macros, but apart from special tasks, it's better not using them in packages or personal macros. The macro \@gtempa is used as "global scratch macro" and its meaning should always be set globally.

Also registers \muskip0 to \muskip9 are available as scratch registers, but I don't know of any packages that uses them.

Usage of scratch conditional and registers should follow some simple rules.

  1. Never rely on their value before using them, therefore initialize their value at the start of the job.

  2. Avoid calling macros that might use the same scratch registers during the time you need those register to have a relied upon value, unless the call is made inside a group, so that the previous value will be restored at group end.

  3. In case of doubt, don't use scratch registers, but allocate your own.

Any register can be used as scratch register, provided this is done inside a group and following the rules above (but with more care about possible value clobbering). So it's fairly common to find \count0 and \count2 used as scratch registers inside a group; this is safe, provided nothing that can trigger a page break is performed. Why? The value of the counters \count0 to \count9 is recorded in the DVI or PDF output during a \shipout operation (if nonzero, for the registers numbered 1 to 9); the LaTeX counter page is actually \count0.


A very common pitfall is in the usage of box registers which do follow the group structure, with the peculiarity that \box and \unhbox destroy the current incarnation of the box register. So, after

\setbox0=\hbox{foo}\begingroup\box0\endgroup 

the box register 0 will be void. On the other hand,

\setbox0=\hbox{foo}\begingroup\setbox0=\hbox{bar}\box0\endgroup 

will result in box register 0 still containing \hbox{foo}.

The LaTeX kernel allocates some scratch registers and defines a scratch conditional. The complete list is

\newcount\@tempcnta \newcount\@tempcntb \newif\if@tempswa \newdimen\@tempdima \newdimen\@tempdimb \newdimen\@tempdimc \newbox\@tempboxa \newskip\@tempskipa \newskip\@tempskipb \newtoks\@temptokena 

Notice that for the first two \newcount is used, rather than \newcounter. All these registers and \if@tempswa (with the companion macros \@tempswatrue and \@tempswafalse) must be used only locally, so never assigned values with the \global prefix.

The register allocation mechanism always leaves free the first ten register numbers, so also

\dimen0 ... \dimen9 \skip0 ... \skip9 \toks0 ... \toks9 

and box registers 0 to 9 are free for scratch usage. An agreed upon convention (that unfortunately some packages don't follow) is that even numbered scratch registers should be used locally, and odd numbered ones should be used globally. Also for local usage are

\count@ \dimen255 \skip255 \toks255 

but not box register 255; \count@ is an alias for \count255, actually, while \dimen@, \skip@ and \toks@ stand for the 0 register of each type.

The kernel uses also \reserved@a, \reserved@b, \reserved@c, \reserved@d and \reserved@e as scratch macros, but apart from special tasks, it's better not using them in packages or personal macros. The macro \@gtempa is used as "global scratch macro" and its meaning should always be set globally.

Also registers \muskip0 to \muskip9 are available as scratch registers, but I don't know of any packages that uses them.

Usage of scratch conditional and registers should follow some simple rules.

  1. Never rely on their value before using them, therefore initialize their value at the start of the job.

  2. Avoid calling macros that might use the same scratch registers during the time you need those register to have a relied upon value, unless the call is made inside a group, so that the previous value will be restored at group end.

  3. In case of doubt, don't use scratch registers, but allocate your own.

Any register can be used as scratch register, provided this is done inside a group and following the rules above (but with more care about possible value clobbering). So it's fairly common to find \count0 and \count2 used as scratch registers inside a group; this is safe, provided nothing that can trigger a page break is performed. Why? The value of the counters \count0 to \count9 is recorded in the DVI or PDF output during a \shipout operation (if nonzero, for the registers numbered 1 to 9); the LaTeX counter page is actually \count0.


A very common pitfall is in the usage of box registers which do follow the group structure, with the peculiarity that \box and \unhbox destroy the current incarnation of the box register. So, after

\setbox0=\hbox{foo}\begingroup\box0\endgroup 

the box register 0 will be void. On the other hand,

\setbox0=\hbox{foo}\begingroup\setbox0=\hbox{bar}\box0\endgroup 

will result in box register 0 still containing \hbox{foo}.

Source Link
egreg
  • 1.2m
  • 147
  • 2.8k
  • 4.5k

The LaTeX kernel allocates some scratch registers and defines a scratch conditional. The complete list is

\newcount\@tempcnta \newcount\@tempcntb \newif\if@tempswa \newdimen\@tempdima \newdimen\@tempdimb \newdimen\@tempdimc \newbox\@tempboxa \newskip\@tempskipa \newskip\@tempskipb \newtoks\@temptokena 

Notice that for the first two \newcount is used, rather than \newcounter. All these registers and \if@tempswa (with the companion macros \@tempswatrue and \@tempswafalse) must be used only locally, so *never* assigned values with the \global` prefix.

The register allocation mechanism always leaves free the first ten register numbers, so also

\dimen0 ... \dimen9 \skip0 ... \skip9 \toks0 ... \toks9 

and box registers 0 to 9 are free for scratch usage. An agreed upon convention (that unfortunately some packages don't follow) is that even numbered scratch registers should be used locally, and odd numbered ones should be used globally. Also for local usage are

\count@ \dimen255 \skip255 \toks255 

but not box register 255; \count@ is an alias for \count255, actually, while \dimen@, \skip@ and \toks@ stand for the 0 register of each type.

The kernel uses also \reserved@a, \reserved@b, \reserved@c, \reserved@d and \reserved@e as scratch macros, but apart from special tasks, it's better not using them in packages or personal macros. The macro \@gtempa is used as "global scratch macro" and its meaning should always be set globally.

Also registers \muskip0 to \muskip9 are available as scratch registers, but I don't know of any packages that uses them.

Usage of scratch conditional and registers should follow some simple rules.

  1. Never rely on their value before using them, therefore initialize their value at the start of the job.

  2. Avoid calling macros that might use the same scratch registers during the time you need those register to have a relied upon value, unless the call is made inside a group, so that the previous value will be restored at group end.

  3. In case of doubt, don't use scratch registers, but allocate your own.

Any register can be used as scratch register, provided this is done inside a group and following the rules above (but with more care about possible value clobbering). So it's fairly common to find \count0 and \count2 used as scratch registers inside a group; this is safe, provided nothing that can trigger a page break is performed. Why? The value of the counters \count0 to \count9 is recorded in the DVI or PDF output during a \shipout operation (if nonzero, for the registers numbered 1 to 9); the LaTeX counter page is actually \count0.


A very common pitfall is in the usage of box registers which do follow the group structure, with the peculiarity that \box and \unhbox destroy the current incarnation of the box register. So, after

\setbox0=\hbox{foo}\begingroup\box0\endgroup 

the box register 0 will be void. On the other hand,

\setbox0=\hbox{foo}\begingroup\setbox0=\hbox{bar}\box0\endgroup 

will result in box register 0 still containing \hbox{foo}.