An answer looking at the source code: First we have the macros \@ifundefined
and \@ifdefinable
:
Note that \@ifundefined
takes in strings (technically "the name of the control sequence") as the argument, not the control sequence itself.
However \@ifdefinable
takes in a control sequence as the input. So if it wants to use \@ifundefined
in its implementation, it has to extract the name:
It's not too hard to see the check only works for control sequences, not active characters.
Side note, assuming nobody wants to use this command when \escapechar
is -1 or 32 (space character), it would work correctly.
Side note 2, \@ifundefined
, contrary to what its name implies, is supposed to(*) check if the argument's meaning is either undefined
or \relax
.
Nevertheless, it first uses \ifcsname ... \endcsname
to check if it's undefined
first, then if it is not, construct the control sequence with the name to check if it's \relax
, presumably to
save an entry in the hash table when the name is not defined.
(I suspect in pre-ε-TeX days, only the csname-relax check is performed, then after that the ifcsname
is added in to save an entry; but to maintain backwards compatibility it still need to check if the meaning is \relax -- although I didn't check this in the old LaTeX source code)
Maybe someone who can find want source code of older LaTeX versions can confirm that these versions use just the csname-\relax check.
(*): Or so I think.
\newcommand\~{coffee}
does give the error.\~
is an actual control sequence with an existing definition that is completely different from that of~
(right,se\~norita
)?~
was a shorthand for\~
but that doesn't make sense. By the way I'm a señor :);-)