13

I understand that w.l.o.g. \box0 puts the content of box 0 and clears the content of box 0, while \copy0 puts the content of box 0 and does not change the content of box 0 at all.

Whenever I do \sbox0{All New Content}, I overwrite whatever was stored in box 0 and replace it with "All New Content".

Why is it so important to delete the content of a box when using it, that it was made the default behaviour? With regard to compilation, one might suggest leaving the box unchanged is faster and therefore we should delay deleting the content of a box until it becomes necessary, i.e. when we want to put new content in the box.

5
  • there are two primitives \box and \copy why do you think that \box is the default?
    – touhami
    Jun 27, 2016 at 16:27
  • 1
    @touhami Easy. For once, the syntax tells me that \box is how you use boxes and that's why even the command is named after the thing it manages; a box. Whereas \copy is named after the action that is performed and not the thing it manages. Judging from my programming experiece, such naming occurs later. Further, I use both commands when I want "this box here and now". The command \box is much more intuitive and meaningful as the command \copy, just think about shouting a command at a dog. Besides, read \box more often than \copy in code samples, even on this page.
    – Bananguin
    Jun 27, 2016 at 17:21
  • Do you take in account the primitive \ifvoid?
    – touhami
    Jun 27, 2016 at 19:55
  • Are we getting somewhere witht his?
    – Bananguin
    Jun 27, 2016 at 23:04
  • I don't understand your comment, excuse my english. what i mean is that there is simply two primitives for two possible cases. Now suppose that \box is used in the sense of \copy and some primitive \void for (\box) as you already noticed read \box more often than \copy in code samples that's mean we will write \void more than \box and each time we need one more letter.
    – touhami
    Jun 27, 2016 at 23:45

3 Answers 3

12

At the time TeX was written, conserving memory was important. Typically, when a box has been used the content is no longer needed in the original (i.e. it will be moved to some other box), so memory can conveniently be reclaimed with the behaviour that \box clears the box. When this is not the case, \copy is available. Notably, a box is not a fixed item, unlike say count registers, so the need to avoid build-up is there.

Notably, the behaviour of LaTeX's \usebox is built on \copy not \box, i.e. treating a box like any other 'variable' at the cost of memory usage. Certainly with a modern TeX system there really is no need to use \box routinely for memory reasons (though if one knows that the content is not required, there is no particular reason not to reclaim it).

7

Joseph Wright's answer is to the point: conserving memory was Knuth's main concern when defining the primitives dealing with box registers.

There are however some subtle points.

A box register can be void or it can contain a horizontal box (from \hbox) or a vertical box (from \vbox or \vtop).

If you do \box0 (zero can be any other valid register number) and the register is void, nothing happens. Otherwise the box is delivered, not its contents. The contents of the box can be delivered with \unhbox or \unvbox, depending on the type of box stored in the register.1

The fact is that a box may take a huge amount of memory (huge in comparison with computer memory available in the years TeX was being developed, of course), so reclaiming this memory after delivering a box built with \setbox was most important.

There is also another peculiar aspect of boxes. We know that opening a group and setting a variable activates the mechanism for restoring the value of the variable when the group will end. This also holds for boxes, but, in order to conserve memory, if you have built a box outside the group and deliver it inside, the box register will be destroyed at the upper level!

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

will produce no output. Precisely, the most recent incarnation of \box0 will be destroyed. So if you do

\setbox0=\hbox{ABC}
\begingroup\setbox0=\hbox{DEF}\box0\endgroup
\box0

the last command will deliver the same as \hbox{ABC}. In other words, TeX will not start the mechanism for restoring box registers when ending a group unless it has to, that is, \setbox is used inside the group.

There are six primitives to deal with box registers, in addition to \setbox:

\box      \copy
\unhbox   \unhcopy
\unvbox   \unvcopy

The ones in the right column don't destroy the register's contents.

LaTeX's \sbox builds a horizontal box, because it is defined by

% latex.ltx, line 4796:
\long\def\sbox#1#2{\setbox#1\hbox{%
  \color@setgroup#2\color@endgroup}}

Similarly \savebox stores a horizontal box. Note the protection against color trickling (they're activated if color is loaded). The macro \usebox always does \copy:

% latex.ltx, line 4819:
\def\usebox#1{\leavevmode\copy #1\relax}

Final note: if \setbox (or macros built upon it) is done inside a group, the register will be restored to its previous state when the group ends (unless, as said earlier, some \box command has


1 If the box register is void, TeX possibly switches mode, if it has to, depending on whether \unhbox or \unvbox is used. This is how \leavevmode works: it does \unhbox\v@idbox, under the assumption that the box register \v@idbox is permanently void.

3
  • I didn't know that entering a group triggers a mechanism to save the content of a box register when written to inside the group. This means doing \sbox0 inside an environment is actually quite safe. I always thought box registers are always global and unique (and I merely get lucky not to break anything when actually using box register 0). Does this group-saves-state mechanism apply to all registers and macros? This would make a lot of things much less hacky than I thought they were!
    – Bananguin
    Jun 27, 2016 at 13:52
  • @user1129682 Yes, if you do \def\foo{...} inside a group, the macro will disappear as soon as the group ends (or revert to its previous meaning, if existing). Any assignment in the group, unless declared global, will disappear or be restored in the same way. Only some particular assignments are always global, but this is quite a dark corner involving parameters not of general usage.
    – egreg
    Jun 27, 2016 at 13:57
  • The grouping business is a pain: we have some unresolved issues in expl3 in this area.
    – Joseph Wright
    Jun 27, 2016 at 16:28
6

The box in TeX is implemented (roughly speaking) as a pointer to the vertical/horizontal list of typesetting material included in such box and this data structure can be large and it resides in main TeX memory. When you say \box0 at some place of outer material then only the pointer is placed here and the pointer of box0 is newly set to NULL. The contents of previous \box0 saved in main memory is untouched. This "only-pointer" operation is very simple and inexpensive from machine point of view. On the other hand, \copy0 creates the second copy of the same data structure in main memory, because first instance is pointed at the place of \copy0 and second instance keeps the contents of box0.

Boxes are removed from memory after \shipout. Imagine, that \copy0 is used somewhere in a \shipouted box. This content is removed. This is the reason why you need the second instance of data structure if you need to keep the contents of box0.

5
  • So in truth the memory is not reclaimed after a \box call? This seems to contradict what the others said.
    – Bananguin
    Jun 27, 2016 at 13:54
  • @user1129682 It's not wholly contradictory. After \box, the box register becomes void, but the box itself still exists; it's just transferred to whatever "list" TeX is currently assembling. Ultimately, that list will become the contents of another box, and that box will be put on another list, ... until finally it winds up in a box that is fed to \shipout, and then it will be discarded (after generating a page in the output DVI or PDF file). The other posters are glossing over this delay.
    – zwol
    Jun 27, 2016 at 15:26
  • @user1129682 I don't understand what does mean "memory is reclaimed". The fact is that box register (box0, for instance) is only a structure which includes a value of "hbox/vbox/NULL" and a pointer to box data (to the list of typesetting material). When you do a\box0 b then you create a new typesetting material: a followed by box structure with pointer to the same box data, as were in \box0, and followed by b. Note, that the box data (may be a huge) is not touched in the memory now. Only the box0 register is set to NULL after this operation. The reason was explained in my answer.
    – wipet
    Jun 27, 2016 at 20:44
  • Reclaiming memory means that a particular chunk of memory is not oocupied by the program anymore and the kernel knows about it so this memory can be allocated again to whatever process asks the kernel for more memory. In the procedure you describe no memory is freed at all. If you are right, the people who say memory may be/is reclaimed after \box are wrong.
    – Bananguin
    Jun 27, 2016 at 23:07
  • @user1129682 yes, no memory is freed (disposed) when \box0 is used. If you mean that this implies that other answer are wrong, compare the number of votes. Is it a paradox? And compare the votes of the answer which answers something different than what is in the question: problems about boxes in groups and after groups.
    – wipet
    Jun 28, 2016 at 4:36

You must log in to answer this question.

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