[Tex/LaTex] the difference between \ifx\somecommand\undefined and \ifdefined\somecommand\else

conditionalsmacrostex-core

What is the difference between \ifx\cyrdash\undefined and \ifdefined\cyrdash\else? \cyrdash is any macro.

Best Answer

Of course, they have different syntax.

  1. \ifx\cyrdash\undefined is traditional way to test if a macro is undefined. Of course, \undefined sould not be defined.

  2. There are \ifdefined and \ifcsname primitives in eTeX. They have no other side effects.

  3. LaTeX's \@ifundefined test if a macro is defined or it has the same meaning of \relax. Furthermore, \@ifundefined{undefinedfoo}{...}{...} will makes \undefinedfoo to be \relax.

Normally, there is no difference between

\ifx\foo\undefined A \else B \fi

and

\ifdefined\foo B \else A \fi

eTeX primitives may be a little safer. Say, we don't need to worry about whether \undefined is really undefined.

However, these two usage are different:

% wrong
% \expandafter\ifx\csname foo\endcsname\undefined A \else B \fi % This is always false
\expandafter\ifx\csname foo\endcsname\relax A \else B \fi % This is \@ifundefined

and

\ifcsname foo\endcsname B \else A \fi

In fact, \csname undefined\endcsname makes \undefined to be \relax, while \ifcsname undefined\endcsname makes \undefined unchanged. That's why \ifcsname in eTeX is necessary.


Test code:

\documentclass{minimal}

\long\def\themeaning#1{\string#1: \meaning#1\par}

\begin{document}
\makeatletter\ttfamily

\def\known{abc}
\let\empty\relax

% initial
\themeaning\known
\themeaning\empty
\themeaning\unknown
\hrulefill

% useful eTeX extension
\ifdefined\known yes\else no\fi\par
\ifdefined\empty yes\else no\fi\par
\ifdefined\unknown yes\else no\fi\par
\hrulefill

% Or
\ifcsname known\endcsname yes\else no\fi\par
\ifcsname empty\endcsname yes\else no\fi\par
\ifcsname unknown\endcsname yes\else no\fi\par
\hrulefill

% the meanings are unchanged
\themeaning\known
\themeaning\empty
\themeaning\unknown
\hrulefill

% LaTeX2e kernel
\@ifundefined{known}{yes}{no}\par
\@ifundefined{empty}{yes}{no}\par
\@ifundefined{unknown}{yes}{no}\par
\hrulefill

% \unknown is changed
\themeaning\known
\themeaning\empty
\themeaning\unknown

\end{document}