\protectは、後置されるマクロの展開を抑制する。例えば
\edef\xx{\yy\protect\zz\ww}
のように使うと、通常\edefによって展開される波括弧内のマクロのうち\zzは展開されなくなる。
マクロによっては、その場ですぐに展開されても問題ないものと、すぐに展開されると思い通りに働かないものがあるので\protectを付けて、調節できる。
通常展開されないマクロも\sectionの引数として与えられた場合は例外としてその場で展開される。 これは、\sectionの引数がその場で見出しとして使われるだけではなくて、目次で使われるなど「動く」ので、動いた先の異なる環境下でそのマクロが評価された場合に、意図していたことと異なることが起きるかもしれないため。 \section以外にも\captionや\footnoteなども動く引数を持っている。
しかし、その場で展開されると不都合なマクロがある場合には、展開を抑制するために\protectをつけることで展開を抑制することができる。
\documentclass{jarticle}
\begin{document}
\def\name{Fred}
\section{My name is \name.}
\section{My name is \potect\name.}
\end{document}
このファイルをコンパイルして.auxファイルをみてみると、
\relax
\@writefile{toc}{\contentsline {section}{\numberline {1}My name is Fred.}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {2}My name is \name .}{1}}
のように書かれていて、たしかに\protectをつけるとマクロの展開が抑制されていることが分かる。
LaTeXの命令には使われる場所によって変化するものと変化しないものがある。 例えばフォントを変更するコマンド\bfはどこで使われても意味は変わらない。 一方で\ref{}は引数の内容に依存して結果が変化する。 前者のようなコマンドをrobustなコマンド、後者のように引数を取って変化しやすいコマンドをfragileなコマンドと呼ぶ。 fragileなコマンドを動く引数の中で使う場合には\protectをつけて保護しなければならない。 例えば \rule の場合、
\section{Line \rule[2mm]{20mm}{1mm}}
% ↑エラーが出る
\section{Line \protect\rule[2mm]{20mm}{1mm}}
% ↑実行可能
のようになる。
マクロを定義するときに、\DeclareRobustCommandを用いて、あらかじめrobustなコマンドとして定義しておけば、動く引数の中で用いても問題が生じない。
\DeclareRobustCommand{\shortrule}{\rule[2mm]{20mm}{1mm}}