Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am looking for a way in TeX to check if a macro was defined.

Currently I use a rather tangled way. I exploit a sort of side effect when comparing two macros via \ifx; this command returns:

  • true, if both macros are undefined,
  • false, if one macro only is defined.

Therefore, given a surely undefined macro \undefined and the macro \CheckMe, which may or may not be defined, I can use:

\ifx \CheckMe \undefined
  CheckMe is NOT defined
\else
  CheckMe is defined!
\fi

Is this correct? Can we define a macro ifdef? working like:

\ifdef CheckMe         %or \ifdef \CheckMe 
  CheckMe is defined!
\else
  CheckMe is NOT defined
\fi

I tried with something similar:

\def\ifnotdef#1{\ifx \csname#1\endcsname \undefined}

but it doesn't work.

share|improve this question
1  
Is e-TeX allowed? –  egreg Jun 1 '13 at 19:22
    
@egreg: Difficult to say. Actual problem is I have a large project. Sometime I prefer to compile single files. The idea is to define a \def\nostandalone\true in the main package; in the child files, to be sometimes be compiled alone, I would set on the top:` ` \ifx \nostandalone \undefined \documentclass{paper} \begin{document} \fi .... \ifx \nostandalone \undefined \documentclass{paper} \begin{document} \fi So it should be possible to load e-TeX before \documentclass{paper} with TeX methods. –  antonio Jun 1 '13 at 19:36
2  
If you are using LaTeX, then e-TeX extensions are enabled by default, unless you're using a very old TeX distribution. –  egreg Jun 1 '13 at 19:39
    
@egreg: thanks, I didn't explore e-Tex possibilities. –  antonio Jun 1 '13 at 19:42
    
LaTeX defines a number of conditionals to check whether a macro is defined/not: \@ifdefinable, \@ifundefined Why not use them directly as part of your \ifdef? –  Werner Jun 1 '13 at 20:09

2 Answers 2

up vote 15 down vote accepted

You can't define a macro \ifdef that can work with nested conditionals, because of the way TeX keeps track of \else and \fi. With a naive definition such as

\def\ifdef#1{\ifx#1\undefined}

one could surely say

\ifdef\CheckMe
  \string\CheckMe\space is not defined
\else
  \string\CheckMe\space is defined
\fi

but a construction such as

\ifnum\Acount=\Bcount
  something else
\else
  \ifdef\CheckMe
    \string\CheckMe\space is not defined
  \fi
\fi

will break if \Acount is equal to \Bcount, leaving a stray \fi: the \else will be matched to the first \fi, not to the second, because TeX doesn't expand tokens that are skipped in the true or false branch of a conditional; since \ifdef is a macro and not a conditional, the mismatch will bite you.

A workaround (tracing back to Knuth himself) is to define a macro in the following way:

\def\isundefined#1{TT\fi\ifx#1\undefined}

and call it as

\if\isundefined\CheckMe
  \string\CheckMe\space is not defined
\else
  \string\CheckMe\space is defined
\fi

This works also in nested conditionals because TeX will see the \if and match it with the correct \else or \fi. When expanded, \if TT\fi will do exactly nothing, leaving control to the following \ifx.


If e-TeX is allowed, there's an \ifdefined conditional that avoids choosing a macro name and trusting it will remain undefined:

\ifdefined\CheckMe
  \string\CheckMe\space is defined
\else
  \string\CheckMe\space is not defined
\fi

(notice the reversal of the conditions).

share|improve this answer
    
+1 \ifdefined is what I need! –  antonio Jun 1 '13 at 19:46

Changing slightly your definition, you will obtain Knuth's \ifundefined:

\def\ifundefined#1{\expandafter\ifx\csname#1\endcsname\relax}

It has some limitations, but seems to be that you need.

Here http://www.gust.org.pl/projects/pearls/2006p/index_html (Check if defined, no side effects by Bernd Raichle) you can find a deeper approach, with comments.

share|improve this answer
    
+1 there's always something to learn –  antonio Jun 1 '13 at 19:52

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.