Are \end.... macro names reserved in LaTeX2e?

As others have noted, you may not define any commands starting with \end. The reason is that you may use any latex2e command as an environment (some don't like that design, but that's the way it was designed) so you can go

\begin{small}....\end{small}

even though \endsmall is not normally defined.

If you were allowed to go

\newcommand\endsmall{zzzz}

just if \endsmall is not defined, then you would have been allowed to redefine the small environment with no warning.


Short answer: yes, LaTeX2e does reserve these names, at least as far as \newcommand is concerned. The TeX \def primitive has no such restriction and may be used if you really want to define a command starting \end....

LaTeX2e implements environment foo by looking for a macro \foo and possibly one \endfoo. These are created for example by

\newenvironment{foo}{}{}

To prevent issues which could arise from doing

\newcommand\endfoo{}

this is checked for and specifically blocked. Imagine for example you didn't know about the implementation and did exactly the above: you'd have a surprising result for one of the two cases without the check.

The issue here really is of course that LaTeX2e is rather 'permissive' about what counts as an environment. There is no specific namespace for the implementations and you don't have to define \endfoo at all. The 'LaTeX3 vision' is to address this properly: if you look at xparse it does have the idea of a separate namespace built in, but of course at present has to define LaTeX2e-compatible commands.


The command \newcommand{<cs>}... does \@ifdefinable{<cs>} for testing if the control sequence is available; the definition is

\long\def\@ifdefinable #1#2{%
      \edef\reserved@a{\expandafter\@gobble\string #1}%
     \@ifundefined\reserved@a
         {\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
          \ifx \reserved@b\@qend \@notdefinable\else
            \ifx \reserved@a\@qrelax \@notdefinable\else
              #2%
            \fi
          \fi}%
         \@notdefinable}

The first bit

 \edef\reserved@a{\expandafter\@gobble\string #1}

produces the macro name without the backslash (at least if \escapechar has its usual value), storing it in \reserved@a; then this is fed to \@ifundefined. If the requested macro passes the test,

\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil

is performed, which stores in \reserved@b the first three characters in the macro name (or fills it with x's to arrive at three anyway). Then \reserved@b is compared to \@qend whose expansion is

% latex.ltx, line 794:
\edef\@qend{\expandafter\@cdr\string\end\@nil}

that is, it contains the stringified (category code 12) version of end. In this case it calls \@notdefinable; the same it does if \reserved@a contains exactly \relax (not to redefine this primitive).

The second argument is the (massaged) definition text, that is so gobbled if the full test is not passed.

You might redefine \@qend to be anything that can't be produced by \string, say \def\@qend{$}, and be able to define commands whose name starts with end. Don't.

Tags:

Macros