Wenn Du Register nur lokal verwenden willst, solltest Du trotzdem nicht bereits belegte Register dafür verwenden. Jedenfalls gilt das, wenn Du Seiteneffekte während der Abarbeitung Deines Codes nicht ausschließen kannst. Solche Seiteneffekte können beispielsweise dann auftreten, wenn man fremde Makros innerhalb der entsprechenden Gruppe verwendet oder Ausgaben produziert, die einen Aufruf der asynchronen Ausgaberoutine von LaTeX nach sich ziehen können.
Der Grund für dieses Verbot ist einfach: Es ist nicht ausgeschlossen, dass die fremden Macros oder die Ausgaberoutine die Boxregister unverändert benötigen oder selbst verändern. Dies kann sogar global erfolgen, da einige Box-Primitiven auch `\global` erlauben.
Benötigt man einige wenige Register nur kurzzeitig, und will deshalb keine Register global belegen und damit dem Register-Pool entziehen, kann man die speziell dafür vom LaTeX-Kern vorgesehenen Register verwenden. Bei den Boxen ist das in erster Linie `\@tempboxa`. Aber auch in diesem Fall sollte man daran denken, dass der Aufruf eines Makros dieses Register jederzeit ändern kann. Man sollte es also wirklich nur lokal verwenden und nach einem Fremdmakro nicht mehr auf seinen Inhalt vertrauen. Im Idealfall hält man eigene Änderungen an `\@tempboxa` außerdem lokal.
Darüber hinaus gibt es bei einigen Registern noch eine Art stillschweigenden Vorrat an lokal verwendbaren Registern. Bei den Boxen sind das die Boxen 0 bis 9, die sozusagen *kurzzeitig* verwendet werden können.
Nach einer stillschweigenden Konvention sind die geraden Boxen 0, 2, 4, 6, und 8 dabei für lokale Änderungen vorgesehen. Man kann also beispielsweise mal eben Box 0 mit beliebigem Inhalt füllen, dann die Box manipulieren und direkt ausgeben. Zwischen dem Füllen der Box und der Ausgabe der Box sollten aber keine Aktionen stattfinden, die nicht unter der Kontrolle dessen stehen, der die Box füllt. Jede andere Anweisung darf die Box nämlich ebenfalls verwenden, kann sie also insbesondere auch löschen over verändern!
Die ungeraden Boxen 1, 3, 5, 7 und 9 sind für globale Änderungen vorgesehen. Hier darf man also nicht einmal beim Füllen der Box beliebigen Code verwenden, weil dieser diese Boxen selbst (global) verändern könnte.
Andere Boxen, die man nicht mit `\newbox` angefordert hat, darf man auf keinen Fall in einem Kontext verändern, in dem andere Makros oder die Ausgaberoutine zum Zuge kommen könnten. Wurden für diese nämlich die entsprechende Register mit `\newbox` oder `\newsavebox` reserviert, wären sie zum Einen durchaus berechtigt die entsprechende Register lokal oder global zu ändern und haben des Weiteren auch ein Anrecht auf die Unversehrtheit der Registerinhalte. Man würde also fremden Code kompromittieren. So etwas gehört sich nicht nur nicht, es verbietet sich von vorn herein!
Bei den Boxen kommt hinzu, dass diverse davon für *inserts* (siehe `\newinsert`) benötigt werden. Diese werden von LaTeX beispielsweise für Fußnoten verwendet und global vom Ende des normalen Registerpools belegt. Ebenso werden Boxregister für Gleitobjekte benötigt, die jedoch auf normalem Wege reserviert werden. Auch diese werden jedoch global belegt. Unerlaubte Verwendung fremder Boxregister kann also sehr schnell unabsehbare Nebenwirkungen haben!
Will man trotzdem einige Register lokal verwenden, so muss man Sorge dafür tragen, dass man diese Register aus dem Pool bezieht und kann sie auch nur dann wieder freigeben, wenn zwischenzeitlich nicht weitere Register belegt wurden. Dazu eine Beispielumgebung für LaTeX:
\makeatletter% Diese Anweisung wird nur benötigt, wenn der Code _nicht_ in einem Paket
% oder einer Klasse verwendet wird.
\newcount\@firstlocalbox
\newcount\@lastlocalbox
\newenvironment{localboxes}[1]{% Der Parameter gibt die Anzahl der zu reservierenden
% Register an
% Wir belegen die Register in einer Schleife,
% damit das auch mit etex.sty noch funktioniert!
\@tempcnta=\z@
\@firstlocalbox=\count14 % Hack: Verwendung von internem LaTeX-Wissen!
\@whilenum\@tempcnta<#1 \do{%
\advance\@tempcnta by\@ne
\expandafter\newbox\csname localbox\romannumeral\the\@tempcnta\endcsname
}%
\@lastlocalbox=\count14 % Hack: Verwendung von internem LaTeX-Wissen!
}{%
\ifnum \@lastlocalbox=\count14
% Zwischenzeitlich hat niemand weitere Box-Register belegt,
% also können wir die Register wieder ``freigeben''
\global\count14=\@lastlocalbox
\else
\@latexerr{cannot release local box registers}\@ehc
\fi
}
\makeatother% Diese Anweisung darf nur verwendet werden, wenn der Code _nicht_
% in einem Paket oder einer Klasse verwendet wird.
Innerhalb der Umgebung sind die *lokalen* Boxregister dann unter den Namen `\localboxi`, `\localboxii`, `\localboxiii`, `\localboxiv` etc. ansprechbar.
Die Umgebung kann theoretisch auch geschachtelt verwendet werden. Falls nicht mehr genügend Register zur Verfügung stehen, wird derzeit ggf. mehrfach ein Fehler ausgegeben.
Einen noch besseren Ansatz bietet das Paket [`localloc`][1]. Dieses arbeitet aber nicht mit eTeX, also auch nicht mit dem [etex-Paket][2] zusammen.
Als Merksatz gilt: **Verwende keine Register, die Du nicht selbst mit der entsprechenden Anweisung des verwendeten Formats reserviert hast!**
Der Merksatz gilt nicht nur für LaTeX, sondern für alle Formate. Bei LaTeX und plainTeX heißt die Low-Level-Anweisung zur Reservierung von Boxregistern `\newbox` (diese wurde in obigem Beispielcode deshalb auch verwendet). LaTeX stellt darüber hinaus noch die Anwender-Anweisung `\newsavebox` bereit, die ihrerseits auf `\newbox` basiert und in der Regel vorzuziehen ist, weil sie mit denselben Sicherheitsmechanismen wie `\newcommand` ausgestattet ist.
Die Pakete [`localloc`][1] und [`etex`][2] basieren hingegen auf internem Wissen aus dem LaTeX-Kern über die Implementierung der `\new…`-Anweisungen zur Reservierung von Registern. Da sie in unterschiedlicher Weise an denselben Stellen der Implementierung eingreifen, sind sie leider inkompatibel zueinander und können nicht gleichzeitig verwendet werden!
Obiger Beispielcode für die lokale Reservierung von Boxregistern ist ebenfalls ein Teilverstoß gegen den Merksatz, da er zusätzlich internes Wissen über die Implementierung von `\newbox` verwendet. Er ist insbesondere nicht kompatibel mit [`localloc`][1] dafür aber mit [`etex`][2]. Der eigentliche Teilverstoß liegt aber nicht in der Reservierung von Boxregistern, die sauber per `\newbox` erfolgt. Der Teilverstoß liegt darin, dass diese mit Hilfe von internem Wissen wieder freigegeben werden. Genau daraus resultiert auch die Inkompatibilität mit [`localloc`][1].
Die aufgezeigten Inkompatibilitäten sind nur ein sehr kleiner Ausschnitt aus den Gefahren, die aus Verstößen gegen den Merksatz resultieren.
[1]: http://www.ctan.org/pkg/localloc
[2]: http://www.ctan.org/pkg/etex-pkg