I'm trying to do the same as this one, but with \def, \gdef or \xdef instead.

Very quick summary of the other question:
I wanted to print the command (not the contents of the command) regardless of it being defined by \csname or not. Solution was to check whether the first string is \csname or the command.

So \def needs an \expandafter if used with \csname. If not then everything is ok:

\expandafter\def\csname str\endcsname{String}

Both are correct. But if I wanted to change \str or \csname str\endcsname with an argument (#1). Now it's not known whether I need to use \expandafter or not. If used when not needed, it results in an error. I wrote this (in analogy with the other question)


\defcmd\csname str\endcsname{String}

This will absorb the first string after \defcmd as argument (#1), check whether it's \csname or anything else and will then replace itself either with \expandafter\def or \def and place the argument back.
When running that code, no problem at all. But when I try to output the command (either directly or in a file) I get the following error:

! Use of \str doesn't match its definition

And I have no clue why that is. (l.24 is one line after the use of \str)

  • you didn't put in the extra expandafter: I said in comments in the other question that it is confusing if you don't:-) Jul 24, 2012 at 13:14

2 Answers 2


Let's see what happens in the two cases.


This becomes


and the test is false, so what remains in the input stream is


which is perfectly acceptable for TeX, but has two issues: the token \str must be followed by \fi and there will also be an error about a forgotten \fi

\defcmd\csname str\endcsname{foo}

This becomes

\ifx\csname\csname\expandafter\def\csname\else\def\csname\fi str\endcsname{foo}

and TeX will leave in the input stream

\expandafter\def\csname\else\def\csname\fi str\endcsname{foo}

Now \expandafter expands \csname which will get rid of what is between \else and \fi, resulting in


as required.


We have to get rid of the \fi before \def is executed. One way has been shown by David. Alternatively:


In the case of \def\str{foo} we have


which is false, so what remains is


which becomes (the expansion of \fi is empty)


and finally


In the case of \defcmd\csname str\endcsname{foo} we'd have


and, since the test is true,


The expansion of \else is empty and gets rid of everything up to the matching \fi, so we are left with


and finally

\expandafter\def\csname str\endcsname{foo}

which is what wee need.

"Skipping tokens" in a conditional is performed differently when the condition is true or false: \iftrue X\else Y\fi leaves X\else Y\fi and it will be the expansion of \else that gets rid of Y; conversely, \iffalse X\else Y\fi will leave Y\fi, skipping tokens up to and including \else. The expansion of \fi is empty, but until it's not expanded it remains in the input stream.

Here I used \iftrue and \iffalse to be any conditional construction that returns true or false, respectively; X and Y represent any token list.

  • Wow, that's some insight in how LaTeX works. Didn't know a lot of stuff you mentioned. Thanks again egreg :).
    – Didii
    Jul 24, 2012 at 13:46



\defcmd\csname str\endcsname{String2}



Two classic sins: forgetting to have enough \expandafter and forgetting % at ends of lines:-)

If you replace the definition with your original, the \show will show

 tex foo
This is TeX, Version 3.1415926 (TeX Live 2012)
> \str=macro:
 \fi ->String.
l.23 \show\str

> \str=macro:
l.28 \show\str

So the second call actually worked as intended but the first defined \str as if you had done


and it requires a \fi token to follow its use. That is why you get an error if you try to use the defined token later.

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.