In C, preprocessor macros can have unexpected effects because their arguments can be evaluated multiple times. For example, the following code:
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int i = 5, j = MAX(i++, 0);
becomes:
int i = 5, j = ((i++)>(0) ? (i++) : (0));
and the variable i
will have the value 7—not 6 as expected—because the macro's arguments are repeated in the macro definition.
Does LaTeX have similar issues? For example, what would happen in the following:
\newcommand{\foo}[1]{#1 #1}
\foo{\somethingwithsideeffects}
Would the side effects happen twice? If so, how can that be avoided? Can \edef
be cleverly used to cause side effects to happen only once? Or \sbox
(assuming the argument is something you want boxed)? Or maybe some way to automatically remove tokens that have side effects from #1
?
Is this a problem in practice?
Best Answer
The side effect can occur in TeX as well. As far as I know there is no real way to avoid them. That is, if you produce something like you did in your example, there is no way to change
\foo
to accommodate that. Take the following example:This will produce
x y
, because first the#1
s in foo are replaced by their replacement text (\temp
) and then those are expanded one at a time. That means\switch
is changed before the second\temp
is expanded. In this simple example grouping would help. If we changed the definition of\foo
to\def\foo#1{{#1}{#1}}
then it would printx x
. However, this stops working when we\gdef
instead of\def
\switch
inside of\temp
. The problem is, if we can't modify\temp
then we can't really do anything about that in\foo
. So if you pass a macro with side effects to a macro that uses that argument more than once, it can lead to problems.