4

The following code fails to compile:

\documentclass{article}
\makeatletter
\newcommand{\foo}{xyzzy}

\@ifdefinable{xfoo}{\relax}
\makeatother

\begin{document}
...
\end{document}  

More precisely, it fails with the following error:

LaTeX Error: Command \foo already defined.
Or name \end... illegal, see p.192 of the manual.

This is essentially because of the way \@ifdefinable is implemented internally.

Question. Is there a good workaround that doesn't involve renaming \foo or replacing \@ifdefinable with a different command? (In my actual situation, \foo is provided by one package and \@ifdefinable is being used by another package.)

3

The argument to \@ifdefinable should be a control sequence, not a string of characters. The error is spurious due to the fact that \@ifdefinable strips of the first character in the stringified form of the argument, assuming it's a backslash.

So you should do

\@ifdefinable{\xfoo}{...}

You're perhaps confusing this with \@ifundefined: if you want to see if \foo is undefined (or \relax) the test is

\@ifundefined{foo}{code for undefined}{code for defined}

This is indeed a bug in aliasctr.sty, where line 59 is

 59       \@ifdefinable{c@#1}{%

and it should be

 59       \expandafter\@ifdefinable\csname c@#1\endcsname{%
  • That explains why the first character goes missing. The erroneous invocation is not mine, though – it comes from the definition of \@counteralias (in aliasctr.sty of the thmtools package). – Zhen Lin Jul 31 '15 at 17:40
  • @ZhenLin Sorry, bug in the package! – egreg Jul 31 '15 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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