\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}
,因此它根本没有进入循环。你错了。