# How to check if a command is empty, with a variable name?

I'm doing this:

\documentclass{article}
\begin{document}
\newcounter{bar}
\newcommand\checkit{
\ifx\csname foo\romannumeral\the\value{bar}\endcsname\empty
empty
\fi
}
\newcommand\foovi{hello}
\setcounter{bar}{6}
\checkit
\renewcommand\foovi{}
\checkit
\end{document}


I'm getting an empty document, while a single word "empty" is expected. What's wrong?

• @Mico can you please suggest how to rewrite this better? I'm not married to \ifx, any other options are welcome! Aug 30 at 5:00
• Have you consulted the posting How can I check in LaTeX (or plain TeX) whether a command exists, by name?
– Mico
Aug 30 at 5:08
• Then you probably also saw Joseph Wright's warning, right? I'd give Joseph Wright's answer a try: \makeatletter \newcommand\checkit{The command foo\romannumeral\the\value{bar} \@ifundefined{foo\romannumeral\the\value{bar}}{ doesn't exist!}{ exists: \csname foo\romannumeral\the\value{bar}\endcsname{}}} \makeatother.
– Mico
Aug 30 at 5:18
• @Mico you are right, I updated my question Aug 30 at 5:21

There is an \expandafter missing. Beside this: there is a difference if a command is defined as long or as short:

\documentclass{article}
\begin{document}
\newcounter{bar}
\newcommand\checkit{%
\expandafter\ifx\csname foo\romannumeral\value{bar}\endcsname\empty
empty
\fi
}
\newcommand\foovi{hello}
\setcounter{bar}{6}
1. \checkit

\renewcommand\foovi{}
2. \checkit

\renewcommand*\foovi{}
3. \checkit

\end{document}


There are a few issues with your code:

• \ifx doesn't expand its arguments, but only compares the first two tokens following it, in your case \csname and f, which always yields false. You need to use \expandafter to build the \csname before \ifx does its job.


• your macro's replacement text starts with a spurious space, you have to comment out the line ending after {, like so: \newcommand\checkit{%. You don't have to comment out line endings after macro names, so the line containing the \ifx and \fi are fine, another (possibly) unwanted space occures after the word empty.

I don't know what should happen in the case that \foovi isn't yet defined, so I decided to let this case throw the <false> branch. You can easily change that if you want.

I defined your macro \checkit to take two arguments (not immediately, but the used \@secondoftwo, \@secondofthree and possibly \@firstoftwo will take those arguments). So the macro will now behave as \checkit{<true>}{<false>} and execute the corresponding branch if the macro has the meaning \@empty (which is the same as \empty, but since we're in \makeatletter we could as well use the less likely to be redefined macro \@empty).

\documentclass[]{article}

\newcounter{bar}

\makeatletter
\providecommand\@secondofthree[3]{#2}
\newcommand\checkit
{%
\@ifundefined{foo\romannumeral\value{bar}}%
{%
% undefined
\@secondoftwo % should result in <false>
%\@firstoftwo % should result in <true>
}
{%
\expandafter\ifx\csname foo\romannumeral\value{bar}\endcsname\@empty
\expandafter\@secondofthree
\fi
\@secondoftwo
}%
}
\makeatother

\begin{document}
\setcounter{bar}{6}
\checkit{empty}{not empty}

\newcommand*\foovi{hello}
\checkit{empty}{not empty}

\renewcommand*\foovi{}
\checkit{empty}{not empty}
\end{document}


Result:


• The other answers also mention the \expandafter needed for \ifx. Aug 30 at 15:15