[Tex/LaTex] \setbox vs. \sbox and \savebox – What are the differences I need to know about

boxesplain-tex

What's the difference between using TeX's \setbox and LaTeX's \sbox and \savebox?

Best Answer

\sbox is a short form of \savebox in the same way that \mbox is a short form of \makebox for the common case where you do not need to specify any lengths and want the natural size of the box. \setbox is the underlying TeX primitive so it does not read its arguments as a normal macro (like the comparison between \hbox and \mbox) and it is not safe to use with colour commands unless you take extra precautions to insert extra groups, that the LaTeX versions do automatically.

Added note: One other important difference I forgot before, it is implicit in the examples below but not highlighted. \sbox\boxa{aa} is like \setbox\boxa\hbox{....} so it supplies the \hbox. So if you need to save vertical material you need to save a vbox in an hbox, whereas with \setbox you can do \setbox\boxa\vbox{aaa \par bbb} however there is not much difference between a vbox and an hbox containing a vbox, unless you start using unboxing primitives, so this difference isn't a major one in practice.

UPDATE examples added as requested (the source is more informative than the output)

\documentclass{article}
\tracingonline2
\showboxdepth10
\showboxbreadth10
\usepackage{color}

%these are the same except the latex version  \newsavebox
%checks that the name is not already used.
\newbox\boxa
\newsavebox\boxb

\begin{document}


\setbox\boxa\hbox{abc}
\sbox\boxb{abc}

The above look the same but see
%\showbox\boxa
%\showbox\boxb

\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x15.27782
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 c

! OK.
\end<verbatim}

\begin{verbatim}
> \box27=
\hbox(6.94444+0.0)x15.27782
.\pdfcolorstack 0 push {0 g 0 G}
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\kern0.27779
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
\end{verbatim}

The LaTeX version has extra specials inserted so that colour acts like
fonts and stays with the box.

If you \emph{use} colour in the box it gets more serious

\setbox2\vbox{{% stop this broken test leaking to the page


\setbox\boxa\hbox{ab \color{red}c}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x18.33336
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
\end{verbatim}

See the box just contains a color push and the color pop is not saved
in the box but happens at the point of the save, so the colour stack
is corrupted which depending what you are doing can crash your printer
or just get the wrong colours or\ldots.

\setbox\boxa\hbox{{ab \color{red}c}}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.0)x18.33336
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
\end{verbatim}
see that fixed it and the pop and push are now matched.

\sbox\boxb{ab \color{red}c}
%\showbox\boxb
\begin{verbatim}
> \box27=
\hbox(6.94444+0.0)x18.33336
.\pdfcolorstack 0 push {0 g 0 G}
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 b
.\glue 3.33333 plus 1.66666 minus 1.11111
.\pdfcolorstack 0 push {1 0 0 rg 1 0 0 RG}
.\OT1/cmr/m/n/10 c
.\pdfcolorstack 0 pop
.\pdfcolorstack 0 pop
\end{verbatim}
Latex gets it right.
}}% this box not put into the page so the colour stack is not
  % corrupted.

Even without colour there are differences

\setbox\boxa\hbox{aa\verb|\relax|}
%\showbox\boxa
\begin{verbatim}
> \box26=
\hbox(6.94444+0.8333)x41.49976
.\OT1/cmr/m/n/10 a
.\OT1/cmr/m/n/10 a
.\hbox(0.0+0.0)x0.0
.\OT1/cmtt/m/n/10 \
.\OT1/cmtt/m/n/10 r
.\OT1/cmtt/m/n/10 e
.\OT1/cmtt/m/n/10 l
.\OT1/cmtt/m/n/10 a
.\OT1/cmtt/m/n/10 x
\end{verbatim}

%\sbox\boxb{aa\verb|\relax|}% commented out as it makes an error.

\begin{verbatim}
! Missing } inserted.
<inserted text> 
\end{verbatim}


\end{document}