# How to use \@ifdefinable{xfoo}{…} when \foo is already defined?

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.)

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