Nach `\if` expandiert TeX so lange, bis zwei nicht expandierbare Tokens gefunden werden. Ist das nicht expandierbare Token eine Kontrollsequenz, also beispielsweise ein TeX Primitiv, so wird diesem der Code 256 zugeordnet. Ansonsten wird der Zeichencode des Tokens (kann bei TeX zwischen 0 und 255 liegen, da TeX nur 8-Bit-Zeichen verarbeitet) genommen. Diese beiden Codes werden dann verglichen.
Beispiele:
- `\if\noexpand\end\relax ja\else nein\fi`
Ergibt: `ja`, weil `\noexpand\end` zu einem nicht expandierbaren `\end` expandiert und diesem als Kontrollsequenz dann 256 zugeordnet wird und `\relax` nicht expandierbar ist und direkt 256 zugeordnet bekommt.
- `\ifx abja\else nein\fi`
Ergibt: `nein`, weil `a` und `b` nicht expandierbare Tokens sind und der Zeichencode von `a` und `b` nicht gleich ist.
- `\def\a{a}\if a\a ja\else nein\fi`
Ergibt: `ja`, weil das erste `a` nicht expandierbar ist, `\a` ebenfalls zu `a` expandiert und dann die beiden `a` den gleichen Zeichencode haben.
- `\def\a{a}\if \a aja\else nein\fi`
Ergibt: `ja`, weil `\a` zu `a` expandiert und dann die beiden `a` den gleichen Zeichencode haben.
- `\def\a{ab}\def\b{ab}\if \a\b ja\else nein\fi`
Ergibt: `nein`, weil `\a` zu `ab` expandiert, das zwei nicht expandierbare Tokens sind, `a` und `b` unterschiedlichen Zeichencode haben und damit der `\else`-Teil ausgeführt wird.
- `\def\a{aa}\def\b{bb}\if \a\b ja\else nein\fi`
Ergibt: `bbja`, weil `\a` zu `aa` expandiert, das zwei nicht expandierbare Tokens sind, `a` und `a` denselben Zeichencode haben und dann `\b ja` vor dem `\else` übrig bleiben.
- `\def\a{aa}\def\b{bb}\ifx \a\b ja\else nein\fi`
Ergibt: `nein`, weil `\ifx` anders als `\if` funktioniert.
Als weiterführende Literatur empfehle ich hierzu »[TeX by Topic][1]« (Kapitel 13) oder »The TeXbook«.
Im LaTeX-Kern wird `\if` beispielsweise verwendet, um zeichenweise die Ein-Zeichen-Optionen für die Gleitumgebungsoptionen mit einzelnen Buchstaben zu vergleichen oder die einzelnen Zeichen einer kleinen, römischen Zahl in Großbuchstaben für eine große, römische Zahl zu wandeln oder die Platzierungs-Optionen von `\makebox`, `\parbox`, `minipage` oder `tabular` zeichenweise mit entsprechenden Buchstaben zu vergleichen.
`\@ifundefined` und `\@ifpackageloaded` sind übrigens nicht mit `\if`, `\ifx` oder `\ifodd` zu vergleichen, da sie eine ganz andere Syntax haben. Die `\if… … \else … \fi`-Syntax ist für diese nicht verwendbar, da TeX bei dieser Syntax eine Abkürzung nimmt, sobald es weiß, ob die Bedingung zutrifft oder nicht. Es wird nämlich je nachdem der true-Teil oder der else-Teil einfach übersprungen, wobei nicht mehr expandiert wird, sondern lediglich Ebenen von `\iftrue … \else … \fi` und `\iffalse … \else … \fi` mit berücksichtigt werden. Deshalb darf man auf keinen Fall eine Definition wie:
\def\@ifundefined#1{\expandafter\ifx\csname #1\endcsname\relax}
verwenden. Diese würde beispielsweise in
\iffalse
\def\test{ok}%
\@ifundefined\test ok\fi
\else
not ok
\fi
Zu einem Fehler `Extra \else`-Fehler führen, weil `\@ifundefined\test` nicht expandiert würde und damit das erste `\fi` bereits das Ende von `\iffalse` wäre. Aus genau diesem Grund, ist `\@ifundefined` im LaTeX-Kern stattdessen eine Anweisung mit drei Argumenten (wobei die letzten beiden von `\@firstoftwo` oder `\@secondoftwo` gelesen werden). Ich erwähne das, weil Anfänger gerne solche Fehler machen.
[1]: http://www.ctan.org/pkg/texbytopic