# TeX's \write command sometimes induces a spurious vertical space

in the process of debugging a problem with FiXme (reported by Lars Madsen), I fell on this issue which I'm afraid is beyond my expertise. Consider the following MWE:

\documentclass{memoir}
\usepackage{amsmath,amsthm}
\newtheorem{theorem}{Theorem}

\begin{document}
\begin{theorem}
Theorem
\begin{equation*}
Equation
\end{equation*}
\makeatletter\write\@auxout{\string\relax}\makeatother % spurious vspace
\end{theorem}
\begin{proof}
Proof
\end{proof}

\end{document}


The call to \write produces a spurious vertical space in the document (comment this line or call a macro which does nothing to see the difference). I would like to understand what's going on, and whether this should be considered a bug somewhere or not (in the theorem environment?).

Thank you!

• The spurious space vanishes if you use \immediate\write -- maybe the whatsit connected to \write causes this space
– user31729
Jan 25 '17 at 9:07
• Yes. Without \immediate, \write puts a node in the (probably) vertical list here, which is probably why the spacing is affected. In the actual (non minimal) example, \write comes from a call to \addtocontents or \addcontentsline, and down the call stack, there's no \immediate. Jan 25 '17 at 9:15
• Not surprising. The whatsit makes \end{theorem} to be scanned after a new partial paragraph (following the display) has started (better, the vertical list has something after the end of the display). Jan 25 '17 at 9:22

Display environments like proof/theorem etc, and section headings add space before and after the visible text using \addvspace this command tries to look whether a space has just been added to the vertical list and if so do not add the new space if the existing space is greater. This means that say two adjacent theorems do not get a double space between them form the end of one and the start of the other. (The action with a primitive display math is basically similar)
a whatsit from \write (or \color has similar problems) means that it is impossible to see the previous space and so the later environment always adds the full requested space at the start.
The expl3 xgalley code addresses this but it is massively invasive it has to trap every command trying to add anything in vertical mode and make it delay its action and re-order things so that all spacing can be coalesced.