Consider the code below, which after giving me some trouble (especially with catcode 9 and 15), prints all the category codes up to catcode 15.

\the\catcode`\\  \ control character  \\
\the\catcode`{  \ open curly\\
\the\catcode`}  \ closing curly \\
\the\catcode`$  \ dollar\\
\the\catcode`&  \ alignment\\
\ space \\\the\catcode`#  \ sharp\\
\the\catcode`^ \ hat \\
\the\catcode`_ \ underscore \\
\number\catcode`\  \ space \\
\catcode `\y=9
\the\catcode`\y    \ ignored character \\
\the\catcode`a \ letters\\
\number\catcode`@  \ restricted  \\
\number\catcode`~ \ tilde \\
\the\catcode`\%   \ comment\\ 
\catcode`\z = 15 
\the\catcode`\z  \ invalid character \\
%\catcode `\t=16
\ifcat\test 16  16  control sequence\fi

Now, getting TeX to print the catcode 16, has me puzzled. For starters if you uncomment the line, %\catcode \t=16 you get,

! Invalid code (16), should be in the range 0..15. 
  l.23 \catcode\t=16

but, if you test with \ifcat a control sequence is definitely equal to category code 16. So my question is, how can I coerce TeX to say sixteen for a control sequence and how come the error message says 16 is an invalid code, but the TeXbook says it is?

Mildy related question How do I get the category code of a character that is the value of a control sequence?

  • Where in the TeX Book does it refer to a catcode of 16? I thought there were 16 in total, numbered 0 to 15.
    – Werner
    Oct 18, 2011 at 22:55
  • @Werner Chapter 20, page 209 detailing the if commands.
    – yannisl
    Oct 18, 2011 at 23:01
  • Please correct the title to "category code", not character code. Oct 19, 2011 at 8:04
  • @BrunoLeFloch ny bad! Thanks for picking it up!
    – yannisl
    Oct 19, 2011 at 10:10

1 Answer 1


There's really no category code 16. This code is assigned to control sequences (not \let to a character) only for the purposes of \ifcat.

Similarly, character code 256 is assigned to the same tokens for the purposes of \if.

You can get category codes 9 and 15 with


(these are the only characters that have those category codes in the default setting, bytes 0 and 127).

Notice also that \ifcat doesn't compare a token with a number, but two tokens:

\ifcat ab
\ifcat a1

The first evaluates to true, the second to false.

Quoting from the TeXbook, page 209:

\ifcat<token1><token2> (test if category codes agree)
TeX will expand macros following \if until two unexpandable tokens are found. If either token is a control sequence, TeX considers it to have character code 256 and category code 16, unless the current equivalent of that control sequence has been \let equal to a non-active character token.

The key word is considers. Look at page 38:

A token is either (a) a single character with an attached category code, or (b) a control sequence.

Section 506 of "TeX, the program" tells the truth about this: if the next token is not an active character or is a control sequence (not let to a character), then the variable *cur_chr* gets the value 256.

  • Why then this \ifcat\test 16 true\else false\fi is true? Where in the TeXbook does it say it is really no category 16? I read it differently on page 209, chapter 20.
    – yannisl
    Oct 18, 2011 at 23:10
  • 4
    @YiannisLazarides With your definition \test expands to nothing; so \ifcat compares 1 with 6 and their category codes agree.
    – egreg
    Oct 18, 2011 at 23:16
  • Just thinking aloud this is also one of Knuth's jokes \ifcat doesn't compare a token with a number, but two tokens in my ifcat test it definitely compares one with two i.e, cs, number,number???? Two numbers are two tokens, right?
    – yannisl
    Oct 18, 2011 at 23:19
  • @YiannisLazarides Yes, 16 is two tokens and they are unexpandable, so the expansions triggered by \ifcat stop. It's not like \ifcat#=4, to be clearer.
    – egreg
    Oct 18, 2011 at 23:25
  • Where in the tex.web can I find the assignment of catcode 16 to a control sequence? In @<Test if two characters match@>=, I see m:=relax; n:=256; (m is catcode of first token, n is charcode of first token), where relax is 0 ... ? Jan 22, 2019 at 15:56

You must log in to answer this question.

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