\global は \csname…\endcsname の変形です

\global は \csname…\endcsname の変形です

次の最小限の例を検討してください。

\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}

関連情報