From b6a161833289d402986164912aeb9d005857675d Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Mon, 13 Feb 2017 02:09:24 +0100 Subject: [PATCH] =?UTF-8?q?book:=20don=E2=80=99t=20use=20GNU=20extensions?= =?UTF-8?q?=20in=20the=20example=20unnecessarily?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The use of a GNU C extension for bloc expressions is immaterial to the actual problem with C macros that the section tries to show so don’t use it and instead use a plain C way of writing the macro. --- src/doc/book/src/macros.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/doc/book/src/macros.md b/src/doc/book/src/macros.md index 3ccbeb05f01..ae1e1c65dd2 100644 --- a/src/doc/book/src/macros.md +++ b/src/doc/book/src/macros.md @@ -261,36 +261,34 @@ The metavariable `$x` is parsed as a single expression node, and keeps its place in the syntax tree even after substitution. Another common problem in macro systems is ‘variable capture’. Here’s a C -macro, using [a GNU C extension] to emulate Rust’s expression blocks. - -[a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html +macro using a block with multiple statements. ```text -#define LOG(msg) ({ \ +#define LOG(msg) do { \ int state = get_log_state(); \ if (state > 0) { \ printf("log(%d): %s\n", state, msg); \ } \ -}) +} while (0) ``` Here’s a simple use case that goes terribly wrong: ```text const char *state = "reticulating splines"; -LOG(state) +LOG(state); ``` This expands to ```text const char *state = "reticulating splines"; -{ +do { int state = get_log_state(); if (state > 0) { printf("log(%d): %s\n", state, state); } -} +} while (0); ``` The second variable named `state` shadows the first one. This is a problem