5

I'm trying to understand the meaning of \p@ from plain.tex:

\newdimen\p@ \p@=1pt % this saves macro space and time

While trying to figure it out, I stumbled upon strange behavior.

Consider this:

\newdimen\mydimen
\catcode`@=11
\mydimen=10\p@
\showthe\mydimen

The result is 10.0pt

Now add \nonstopmode and \showthe\nointerlineskip at the beginning, so that it becomes:

\nonstopmode
\showthe\nointerlineskip
\newdimen\mydimen
\catcode`@=11
\mydimen=10\p@
\showthe\mydimen

The result is 0.0pt

Following is the log of the second example with \tracingcommands=1 appended.

{vertical mode: \nonstopmode}

{\showthe}
> -1000.0pt.
\nointerlineskip ->\prevdepth 
                              -1000\p@ 
l.4     \showthe\nointerlineskip


{the character -}
{horizontal mode: the character -}
{\dimen11}
! Missing number, treated as zero.
<to be read again> 
                   \global 
\alloc@ #1#2#3#4#5->\global 
                            \advance \count 1#1by\@ne \ch@ck #1#4#2\allocati...
l.5     \newdimen\mydimen

A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)

! Illegal unit of measure (pt inserted).
<to be read again> 
                   \global 
\alloc@ #1#2#3#4#5->\global 
                            \advance \count 1#1by\@ne \ch@ck #1#4#2\allocati...
l.5     \newdimen\mydimen

Dimensions can be in units of em, ex, in, pt, pc,
cm, mm, dd, cc, bp, or sp; but yours is a new one!
I'll assume that you meant to say pt, for printer's points.
To recover gracefully from this error, it's best to
delete the erroneous units; e.g., type `2' to delete
two letters. (See Chapter 27 of The TeXbook.)

{\global}
{\count21}
{\global}
{\immediate}
\mydimen=\dimen16
{\catcode}
{\dimen16}
{\showthe}
> 0.0pt.
l.8     \showthe\mydimen


{\par}
{vertical mode: \par}
)
! Emergency stop.

The questions are: 1) how \p@ works; 2) why the value of \mydimen is 0.0pt in the second case; 3) how to interpret the log.

1 Answer 1

7

No weird error, actually. The primitive \showthe expands tokens in order to find something good for being shown, the rules are the same as for \the.

Since \nointerlineskip expands to \prevdepth -1000\p@ and \prevdepth is legal after \the when TeX is in vertical mode, the current value of \prevdepth is shown, which is -1000pt, because TeX is at the start of a vertical list.

Then -1000 is printed and \p@ expects a dimension, because it's a dimension register. So the next token is expanded, which is \newdimen and no length is found. Error: Missing number, treated as zero. TeX tries to recover by inserting 0, then a unit is missing and TeX adds pt, again for error recovering. Then \newdimen is performed. Now \p@ holds the value 0pt, so \mydimen=1000\p@ results in setting \mydimen to zero.

Plain TeX has

\newdimen\p@ \p@=1pt % this saves macro space and time

and it turns out that \p@ is \dimen11 (but it's irrelevant). When a register appears in the “right-hand side” of an assignment (such as \dimen0=\p@, but the = is optional), the register's value is used for the assignment; when it appears “alone”, TeX assumes it has to perform an assignment to it and this is the case. You'd get exactly the same error if you typed the value of \dimen0\ is in the hope of printing the current value of \dimen0. So, while \dimen0=10\p@ is a correct assignment, -1000\p@\newdimen leads to an error.

Since \p@ is a dimension register, when it appears in the “right-hand side” of an assignment it accepts a factor in front of it, which means multiplication. The default value of \p@ is 1pt (as shown above), so \dimen0=3.4\p@ is the same as \dimen0=3.4pt; it just requires less tokens and might be abused by changing the value of \p@ (say \p@=1bp, for instance).

If you want to show a macro like \nointerlineskip, you need \show, not \showthe.

Caveat: whilst \showthe expands the next token until finding an unexpandable one, \show never expands and displays the meaning of the next token.

5
  • What does it mean, "\p@ expects a dimension"? Add some examples to the answer please. Commented Aug 28, 2015 at 23:00
  • The MWE to reproduce the error is this: \newdimen\x\x\newdimen\y\showthe\x. So, for what purpose the next token after second \x is expanded? If we put a number there (for length), it changes nothing, i.e., \newdimen\x\x4\newdimen\y\showthe\x. What does TeX need to find in the next token, so that no error will be printed? Commented Aug 29, 2015 at 2:24
  • As far as I understood, these rules hold: \p@ = 1pt and R\p@ = Rpt. Are there any other rules, and what R\p@ means? Multiplication, or some TeX trick? Commented Aug 29, 2015 at 2:28
  • 1
    @Igor Liferenko: 4 is not a valid dimen because it is missing the unit. Also, you seem to be unaware that the equals sign is optional when setting a register; \p@4cm is the same as \p@=4cm, and will change the register to contain the value 4 cm.
    – chirlu
    Commented Aug 29, 2015 at 5:02
  • @chirlu Right. Everything is clear now. Commented Aug 29, 2015 at 5:27

You must log in to answer this question.

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