\edef\relax{\relax} 使 \relax 永远挂起

\edef\relax{\relax} 使 \relax 永远挂起

\edef以前我认为将宏添加到其现有定义中总是安全的。但\edef\relax{\relax}会导致\relax永远挂起并且 CPU 非常繁忙。那么 TeX 在那里做什么呢?

答案1

\relax\def\relax{\relax}是不可扩展的,因此这与您可以检查的相同\show\relax。因此,任何使用\relax都会导致它一步扩展为\relax,因此会造成无限循环。

答案2

这绝对是不安全\edef\foo{\foo}如果你所说的“安全”的意思是“得到与以前相同的结果”,那么就去做吧。

假设你有

\newif\ifblurb
\def\foo{\ifblurb A\else B\fi}

然后做

\edef\foo{\foo}

不会产生\foo与之前相同的定义;因为条件一开始是假的,所以你的\edef定义将与

\def\foo{B}

而如果在之后给出\blurbtrue则相当于

\def\foo{A}

换句话说,您获得了替换文本的“扩展”版本,它可能与您想象的一样,也可能不一样。

还有一些需要考虑的事情:当 TeX 处理时\edef,它首先将宏名称和参数文本分开,然后完全扩展给定的替换文本,直到只剩下不可扩展的标记;每个宏都用其当前值扩展;一旦获得新的替换文本,TeX 就会将\def它与参数文本中的原始标记一起使用。

由于\relax不可扩展,您的定义与相同\def\relax{\relax}。请注意,在它\relax变成而不是原始的。

当你稍后说 时\relax,TeX 知道它是一个宏并根据其定义对其进行扩展,因此它会将其替换为\relax并重新开始扩展......

答案3

您的问题声称这\edef\relax{\relax}本身就会导致无限循环。但事实并非如此:

C:\Users\hammerite>tex
This is TeX, Version 3.14159265 (MiKTeX 2.9.7400 64-bit)
**\relax

*\edef\relax{\relax}

*

TeX 在执行包含 的行后立即打印 * 提示符\edef\relax{\relax},因此它根本没有进入循环。你错了。

相关内容