aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2019-04-11 15:36:59 +0000
committerTom de Vries <vries@gcc.gnu.org>2019-04-11 15:36:59 +0000
commitcd7ffd8a9382c78725f3c09b317bdb4739d3654b (patch)
tree4a08e65bc698b0c31880d7529f36992deb14011a
parent657184d086a57eb214dda530035563a1ecc3df10 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/doc/extend.texi26
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.