Subject: [PATCH 3/2] Allow side-effects in second argument to ALLOC_GROW

From: Jonathan Nieder <[email-masked]>
Date: Fri, 8 Oct 2010 12:02:24 -0500

One might be tempted to try

	ALLOC_GROW(ary, ++nr, alloc);

to increase the size of an array by one, and if one tries, the
compiler will happily accept it.  Unfortunately ALLOC_GROW evaluates
its argument at least twice, so the results are generally not what the
caller wanted.

Luckily, it is simple enough to do what the caller meant by storing
the value of the second argument in a temporary.

The first and third arguments still need to be side-effect-free.  The
name of the temporary is nr_ to avoid conflicting with variables the
caller might use in the expansion of ary, nr, or alloc.

Signed-off-by: Jonathan Nieder <[email-masked]>
---
 cache.h |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/cache.h b/cache.h
index 23d6d45..5c9e338 100644
--- a/cache.h
+++ b/cache.h
@@ -438,13 +438,14 @@ extern int init_db(const char *template_dir, unsigned int flags);
  * at least 'nr' entries; the number of entries currently allocated
  * is 'alloc', using the standard growing factor alloc_nr() macro.
  *
- * DO NOT USE any expression with side-effect for 'x', 'nr', or 'alloc'.
+ * DO NOT USE any expression with side-effect for 'x' or 'alloc'.
  */
 #define ALLOC_GROW(x, nr, alloc) \
 	do { \
-		if ((nr) > alloc) { \
-			if (alloc_nr(alloc) < (nr)) \
-				alloc = (nr); \
+		const size_t nr_ = (nr); \
+		if (nr_ > (alloc)) { \
+			if (alloc_nr(alloc) < nr_) \
+				alloc = nr_; \
 			else \
 				alloc = alloc_nr(alloc); \
 			x = xrealloc((x), alloc * sizeof(*(x))); \
-- 
1.7.2.3