5

Somewhat similar to How to erase/delete a counter, I guess, but for \newdimen... So, consider the MWE:

\documentclass{standalone}

\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \newdimen\dx
    \def\mytest{AA}
    \typeout{\meaning\dx, \meaning\mytest}
  \end{tikzpicture}
  \typeout{\meaning\dx, \meaning\mytest}
\end{document}

The code outputs to stdout:

\dimen152, macro:->AA
\dimen152, undefined

I use tikzpicture just as a way to group; it is clear from the output, that the reference to the macro locally defined in the group, does not survive outside the group; however, the reference to the length \dx created by \newdimen did indeed survive.

So in case I want to deallocate / dereference \dx, such that \dimen152 "goes back" to the pool of "unused" \dimens (if at all possible), what should I do?

2 Answers 2

7

The standard register allocation code (both in LaTeX2e and in plain TeX) works globally. As such, once a register is given a name it is never dropped. Following from this, the usual approach to using registers in LaTeX is that they should be assigned in the preamble rather than in the document body.

The etex package (and similar code built in to e-TeX based plain formats) does have a set of 'local allocators', all called \loc.... Thus here you could use \locdimen

\RequirePackage{etex}
\documentclass{standalone}

\usepackage{tikz}

\begin{document}
  \begin{tikzpicture}
    \locdimen\dx
    \def\mytest{AA}
    \typeout{\meaning\dx, \meaning\mytest}
  \end{tikzpicture}
  \typeout{\meaning\dx, \meaning\mytest}
\end{document}

However, as e-TeX gives us 32k registers of each for types count, dimen, muskip, skip and toks, this is not really necessary in practice. TeX runs are 'batch mode', so there is no real need in the vast majority of cases to worry about such things.

Note that if your circumstances are sufficiently controlled, you could use a group and access registers by number. This trick is used for example in l3regex, where a lot of registers are needed and working using numbers is the most sensible approach. It does of course constrain what you can do: low-level and so requiring a good amount of TeX insight.

3
  • 1
    Note: For expl3 we've explored local allocations and at present haven't gone with them.
    – Joseph Wright
    Jun 19, 2014 at 6:15
  • Many thanks for the detailed answer, @JosephWright - it is great to have it as reference! I'd just like one clarification: if "once a register is given a name it is never dropped", does that also mean that there is otherwise no mechanism for "freeing"? E.g. would \let\dx\undefined (where \undefined is any undefined macro) eventually "free" the corresponding register?
    – sdaau
    Jun 19, 2014 at 11:58
  • @sdaau No, that would free the name but not 'tell' the allocator about it. The standard allocator always increments the register number it uses, with no record of 'free' space. That is doable but needs an entirely new approach which does have some form of list of free 'slots'.
    – Joseph Wright
    Jun 19, 2014 at 12:09
1

If you need not load more packages, there is the \globaldefs primitive register. You can type

\globaldefs=-1 \newdimen\dx \globaldefs=0

instead of

\newdimen\dx

The allocation is done locally. But you cannot do global allocation after this local one in the same group. The macro from etex is more elaborate: It does local allocations from second side of the memory array than global allocations.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .