First of all,
\makeatletter is unnecessary in
.cls files, as the default catcode regime includes it; this is presumably to encourage package writers to hide their macros using
@-laden names. For this reason, I believe that using this command is harmless in package files.
However, using the pair of commands together is harmful, because unlike in a document, you do not want to return to the
@ = other setup within the package. These are document commands and the standard ordering
\makeatletter \makeatother assumes that
\makeatother is actually undoing the previous change, whereas in packages, it is the one making the change.
Edit: Here is a more informed answer. According to
source2e.pdf, the following scheme is used to load packages and classes:
- First, the options and such are gathered.
- Then the name of the current file (i.e.
mypackage.sty), along with the catcode of
@, are saved on a stack.
\makeatletter is run and, if appropriate, the requested file is loaded.
- Afterwards, the stack is popped and the pre-package-load state restored.
In other words, the following ignorant code has no effect at all:
However, it is quite possible that a package does not use
\RequirePackage, but just
\input. In that case, the catcode is not protected and indeed, errors can arise, as you can check yourself by making
bad.sty, for example:
If that seems artificial, have a look at
pgfkeys.sty itself: it
pgfkeys.code.tex, and that file, in turn,
pgfkeysfiltered.code.tex. Presumably, the author felt himself safe once within his own package, but did not suspect that someone else might circumvent the package-loading protection mechanisms also!