What is the difference between \ifx\cyrdash\undefined and \ifdefined\cyrdash\else? \cyrdash is any macro.
- 12,311
- 13,332
3 Answers
Of course, they have different syntax.
\ifx\cyrdash\undefinedis traditional way to test if a macro is undefined. Of course,\undefinedsould not be defined.There are
\ifdefinedand\ifcsnameprimitives in eTeX. They have no other side effects.LaTeX's
\@ifundefinedtest if a macro is defined or it has the same meaning of\relax. Furthermore,\@ifundefined{undefinedfoo}{...}{...}will makes\undefinedfooto 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}
- 77,365
According to TeX by Topic \ifx tests macro equality in the following manner.
Equality of tokens is tested in a stronger sense than the above by
\ifx token1 token2
Character tokens are equal for
\ifxif they have the same character code and category code.Control sequence tokens are equal if they represent the same TeX primitive, or have been similarly defined by
\font,\countdef, or some such. For example,\let\boxhor=\hbox \ifx\boxhor\hbox %is true \font\a=cmr10 \font\b=cmr10 \ifx\a\b %is trueControl sequences are also equal if they are macros with the same parameter text and replacement text, and the same status with respect to
\outerand\long. For example,\def\a{z} \def\b{z} \def\c1{z} \def\d{\a} \ifx\a\b %is true \ifx\a\c %is false \ifx\a\d %is falseTokens following this test are not expanded.
The above refers to ifcat here, also found in TeX by Topic. I presume you mean \@ifundefined from the LaTeX kernel when you say \ifundefined. That is simply implemented in the following manner:
\expandafter \ifx \csname cmd name\endcsname \relax
It uses the fact that the \csname mechanism expands to \relax if the csname is not defined. So basically the biggest difference is that \ifx is more flexible, it allows you to check equality of tokens and not simply whether a csname is defined or not. Furthermore, \ifx takes a token, whereas \@ifundefined takes a csname.
- 603,163
- 17,663
- 5
- 55
- 63
Both \undefined as well as \ifundefined are macros and there is no guarantee that they have not been redefined by a some package.
The roots of ifundefined can be found in Exercise 7.7 (p 40) in the TeXBook, where Knuth asked the reader to define such a macro.
When
\csnameis used to define a control sequence for the first time, that control sequence is made equivalent to\relaxuntil it is redefined. Use this fact to design a macro\ifundefined#1such that, for example,\ifundefined{TeX} true text\else false text\fiexpands to the true text if
\TeXhasn't previously been defined, or if\TeXhas been\letequal to\relax; it should expand to the false text otherwise.
You can examine their content using meaning:
\documentclass{article}
\begin{document}
\makeatletter
%\def\undefined{\relax}
\texttt{TeX: \meaning\TeX}\\
\texttt{ifundefined: \meaning\ifundefined}\\
\texttt{@ifundefined: \meaning\@ifundefined}\\
\texttt{undefined: \meaning\undefined}\\
\makeatother
\end{document}
As you can see in LaTeX, they are equivalent. LaTeX also offers @ifundefined.
- 757,742
- 117,160
\ifx\cyrdash\undefinedand\ifdefined\else\cyrdash? – Igor Kotelnikov Oct 15 '11 at 13:37