
次の最小限の例を検討してください。
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\def\foobar{\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}
結果のログ ファイルにはエントリ が含まれます{retaining \testB=macro:->blubb}
が、 に対応するエントリは含まれません\testA
。TeX を理解する限り、これは が\csname...\endcsname
マクロをローカルに\testA
として定義し\relax
、その直後に「blubb」としてグローバルに再割り当てし、その結果、save_stack に保持エントリが追加されることを意味します。
実際のアプリケーションでは、csname-constructions を使用して、個別に名前が付けられたマクロを無限に定義できる必要がありますが、このためスタック オーバーフローが発生しています。(無限ではないかもしれませんが、80000 を超えることは間違いありません...)
私の質問は、保存スタックにスタックされるのを避けるために、-construct をグローバルに初期化する方法はありますか\csname…\endcsname
? または、保存スタックをクリーンな状態に保つ何らかの回避策はありますか?
答え1
割り当てをグローバルにする代わりに\csname
、さらにローカルにすることもできます。
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\def\foobar{\begingroup\expandafter\endgroup\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}
現在、 は\expandafter
グループ内で実行されるため、が開始する前に終了するグループ内でに\csname
定義されている になります。したがって、グローバル定義が発生したときに は未定義になり、保持エントリが回避されるはずです。\testB
\relax
\gdef
\testB
答え2
私は (La)TeX スタックについて何も知りません ( 以外、LOL) が、内部が...にstackengine
なるのを避けるのが目的であれば、\csname
\def
\csname
外側の を実行する前にを展開します\def
。
\documentclass{article}
\tracingrestores=1
\def\foo{\bar\foobar}
\def\bar{\gdef\testA{blabb}}
\expandafter\def\expandafter\foobar\expandafter{\expandafter\gdef\csname testB\endcsname{blubb}}
\begin{document}
{\foo}
\testA
\testB
\end{document}