diff options
author | Tom de Vries <tdevries@suse.de> | 2019-04-11 15:36:59 +0000 |
---|---|---|
committer | Tom de Vries <vries@gcc.gnu.org> | 2019-04-11 15:36:59 +0000 |
commit | cd7ffd8a9382c78725f3c09b317bdb4739d3654b (patch) | |
tree | 4a08e65bc698b0c31880d7529f36992deb14011a | |
parent | 657184d086a57eb214dda530035563a1ecc3df10 (diff) | |
download | gcc-cd7ffd8a9382c78725f3c09b317bdb4739d3654b.zip gcc-cd7ffd8a9382c78725f3c09b317bdb4739d3654b.tar.gz gcc-cd7ffd8a9382c78725f3c09b317bdb4739d3654b.tar.bz2 |
[doc] Note variable shadowing at max macro using statement expression
When suggesting to rewrite the unsafe (with respect to multiple evaluation of
arguments) macro definition:
...
#define max(a,b) ((a) > (b) ? (a) : (b))
...
into the safe macro definition:
...
#define maxint(a,b) \
({int _a = (a), _b = (b); _a > _b ? _a : _b; })
...
mention the variable shadowing problem for:
...
#define maxint3(a, b, c) \
({int _a = (a), _b = (b), _c = (c); maxint (maxint (_a, _b), _c); })
...
2019-04-11 Tom de Vries <tdevries@suse.de>
* doc/extend.texi (@node Statement Exprs): Note variable shadowing at
max macro using statement expression.
From-SVN: r270287
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 26 |
2 files changed, 29 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7131d58..cf4434a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2019-04-11 Tom de Vries <tdevries@suse.de> + + * doc/extend.texi (@node Statement Exprs): Note variable shadowing at + max macro using statement expression. + 2019-04-11 David Edelsohn <dje.gcc@gmail.com> * xcoffout.h (xcoff_private_rodata_section_name): Declare. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 8e0deac..cad7ad4 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -142,14 +142,36 @@ follows: @cindex side effects, macro argument But this definition computes either @var{a} or @var{b} twice, with bad results if the operand has side effects. In GNU C, if you know the -type of the operands (here taken as @code{int}), you can define -the macro safely as follows: +type of the operands (here taken as @code{int}), you can avoid this +problem by defining the macro as follows: @smallexample #define maxint(a,b) \ (@{int _a = (a), _b = (b); _a > _b ? _a : _b; @}) @end smallexample +Note that introducing variable declarations (as we do in @code{maxint}) can +cause variable shadowing, so while this example using the @code{max} macro +produces correct results: +@smallexample +int _a = 1, _b = 2, c; +c = max (_a, _b); +@end smallexample +@noindent +this example using maxint will not: +@smallexample +int _a = 1, _b = 2, c; +c = maxint (_a, _b); +@end smallexample + +This problem may for instance occur when we use this pattern recursively, like +so: + +@smallexample +#define maxint3(a, b, c) \ + (@{int _a = (a), _b = (b), _c = (c); maxint (maxint (_a, _b), _c); @}) +@end smallexample + Embedded statements are not allowed in constant expressions, such as the value of an enumeration constant, the width of a bit-field, or the initial value of a static variable. |