The following shows code snippet taken from multido.tex. I noticed assignments are not ended with %.

  • See \dimen@=#1\advance\dimen@#2 in

      \edef#1{\number\dimen@ sp}}%
  • See again \count@=#1\advance\count@ by #2 in

      \count@=#1\advance\count@ by #2
  • See again \dimen@=#1pt, \dimen@=#2pt and \dimen@=#1pt\advance\dimen@#2 in

      \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}}

Do assignments produce trailing white spaces that have to be ended with %?


Example 1

  \edef#1{\number\dimen@ sp}}%

After #2 there should be \relax. Indeed, if #2 is a register or a parameter such as \z@ or \lineskip, the space provided by the end of line would not be ignored. In this case also % might be used, because the following token is unexpandable (\edef). The token list got from \multido@step@d{\x}{2pt} would be (I denote the space token with •)

\dimen@=\x\advance\dimen@2pt•\edef\x{\number\dimen@ sp}

and the space before \edef would be ignored. But with `\multido@step@d{\x}{\parindent} one would have

\dimen@=\x\advance\dimen@\parindent•\edef\x{\number\dimen@ sp}

and the space token would not be ignored. The fact that it follows a control word is irrelevant: the tokenization phase has already taken place. With \relax after #2 there would be \relax in place of the space token.

Example 2

It's just the same. There should be \relax after #2

Example 3

I'll number lines for clarity.

1    \def\multido@init@r#1#2#3{%
2      \dimen@=#1pt
3      \multido@dimtonum\dimen@#3%
4      \dimen@=#2pt
5      \ifnum\multido@count<\z@\dimen@=-\dimen@\fi
6      \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}}
7    \def\multido@step@r#1#2{%
8      \dimen@=#1pt\advance\dimen@#2
9      \multido@dimtonum\dimen@#1}

There's no need of terminating lines 2 and 4 with %; actually a % at the end of line 4 would be wrong, because TeX would start expanding \ifnum before having performed the assignment to \dimen@ (probably harmless, in this particular case).

The same problem as before is at line 3: the % is good here, because the following token is \dimen@ that's unexpandable; \relax would have been better.

Line 8 should have \relax at the end, for the same reasons as before; not a %, because an argument #2 such as 2pt would trigger the expansion of \multido@dimtonum before the assignment has been performed.


When TeX is scanning for the dimension, unless the quantity being stored is presented in the form of a register, it will continue looking for the number and unit (expanding along the way) until reaching a space or inappropriate character. The space is removed; thus, assignments written as you show them functionally have the same behavior as control words in removing the following whitespace. And of course, if the dimension is a register then the register name will either be a control word itself (thus swallowing the space) or will be a number that TeX will scan for...

That said, some of the assignments you show use an argument (like #2) for the dimension. Someone sneaky or too clever could use a register for that, and then the space would not be eaten because it would be written into the macro definition before the control word is read. In practice, when such data is not under the control of the programmer, it is better to just kill the space with a \relax.

  • 1
    I think you need to use more specific name, i.e., control word instead of control sequence for the sake of clearness. What about the counter? – kiss my armpit Apr 9 '13 at 4:25
  • 2
    \empty would just eat the end-of-line at definition time, but wouldn't solve the next token expansion issue when the argument is an explicit <dimen>. – egreg Apr 9 '13 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.