The following usage of \ifx can be found in several packages and also in answers on this site. What does this syntax exactly mean? Are there any alternatives and drawbacks?

  % ...

(I actually know the answer, but thought this question should exists here. It pops up from time to time. In the unlikely case that it isn't fully answered I will post an own answer in a few days.)


2 Answers 2


It's one of the uncountable ways to check whether an argument is empty. Almost all of them suffer of some drawback: in the case at hand, the argument mustn't be \\.

What does \ifx do? It compares the two tokens following it, without expanding them. The test return success if both tokens are equal in the sense of \meaning or \show:

  • if they are characters (or control sequences \let to a character), they must represent the same (character code, category code) pair

  • if they are control sequences (but not \let to a character), they must have the same meaning; the cases are too many to list them all.

Before analyzing the macro, we should know something about TeX conditional: the abstract form is

\ifZ<test><true text>\else<false text>\fi

where \ifZ denotes one of the primitive conditionals. The <test> can take many forms, depending on \ifZ (it's empty, in some cases); what is important is that the <true text> is everything that goes from the end of <test> to \else (or \fi if \else is missing).

So let's see what happens when we call \mycommand{abc}, that is, the default argument, which is empty, is substituted to #1: the tokens that TeX sees are


Of course the test is true, because the tokens that follow \ifx are both \\.

When we call \mycommand[xyz]{abc}, instead, TeX sees


and TeX compares \\ to x and they are different. But now the <true text> is


(remember: the <true text> is what goes from the test to the \else) and it will be ignored altogether.

This test is quite safe, because it doesn't do expansion; however it might fail miserably if the user calls \mycommand[\\]{abc}, so often different delimiter tokens are used, which are supposed not to creep into user's input (for instance \uchyph or \vfuzz). Another similar test might be


with the caveat that \if does expand what's next until two unexpandable tokens remain. The first token is \relax, which is unexpandable. The second one will be what becomes of the expansion of \noexpand, that is, the first token of #1 (if non empty) but made unexpandable; if #1 is empty, then \noexpand applies to \relax, resulting again in \relax because it's unexpandable.

In both cases some token is reserved (\\ in the first case, \relax in the second one). The safest test is


because the expansion of a non empty #1 can never give a first token equivalent to \relax: even if #1 is \relax, \detokenize{\relax} will give the string \relax (the first token of which is the character \).

Again, if #1 is empty, the test compares \relax to \relax; if #1 is not empty, everything will be ignored up to the \else. Of course it requires that an engine with the e-TeX extensions is run: it won't work with "Knuth TeX".

  • 1
    Incidentally, \show is slightly more powerful than \meaning for control sequences (or active characters) let to a character (\show also shows the \string part). Nov 6, 2011 at 14:56
  • 1
    Indeed \show<token> always begins with <token>=; but the part after = is the same as for \meaning
    – egreg
    Nov 6, 2011 at 15:01
  • 2
    Actually, you're right, what I point out is not specific to control sequences let to a character. The more interesting thing is that \lccode126=97\lowercase{\let~a\show~}\show a distinguishes between the active a let to a letter a and that letter itself, whereas it is not possible to distinguish those using the usual \string, \meaning, \ifx, \if, etc. Nov 7, 2011 at 10:43
\ifx <command> #1 <command> 
  <code for #1 is empty>
  <code for #1 is _not_ empty>

<command> can also be


if #1 is empty (or doesn't exist), then we have \relax=\relax which is true. If #1 is not empty, then we have \relax=#1 which is false (except #1=\relax) and the following \relax doesn't hurt because it does nothing.

With \ifx\\#1\\ the LaTeX kernel does a test for an extension of a filename:

    <no extension #2 is empty, because \\=\\>
    <extension is #2>

You must log in to answer this question.

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