Rollup merge of #39775 - mina86:master, r=steveklabnik

book: don’t use GNU extensions in the example unnecessarily

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 which has
added benefit of being better C code (since the macro now behaves like
a function, syntax-wise).
This commit is contained in:
Corey Farwell 2017-02-15 23:48:12 -05:00 committed by GitHub
commit ef45eca8a5
1 changed files with 6 additions and 8 deletions

View File

@ -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. place in the syntax tree even after substitution.
Another common problem in macro systems is variable capture. Heres a C Another common problem in macro systems is variable capture. Heres a C
macro, using [a GNU C extension] to emulate Rusts expression blocks. macro using a block with multiple statements.
[a GNU C extension]: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
```text ```text
#define LOG(msg) ({ \ #define LOG(msg) do { \
int state = get_log_state(); \ int state = get_log_state(); \
if (state > 0) { \ if (state > 0) { \
printf("log(%d): %s\n", state, msg); \ printf("log(%d): %s\n", state, msg); \
} \ } \
}) } while (0)
``` ```
Heres a simple use case that goes terribly wrong: Heres a simple use case that goes terribly wrong:
```text ```text
const char *state = "reticulating splines"; const char *state = "reticulating splines";
LOG(state) LOG(state);
``` ```
This expands to This expands to
```text ```text
const char *state = "reticulating splines"; const char *state = "reticulating splines";
{ do {
int state = get_log_state(); int state = get_log_state();
if (state > 0) { if (state > 0) {
printf("log(%d): %s\n", state, state); printf("log(%d): %s\n", state, state);
} }
} } while (0);
``` ```
The second variable named `state` shadows the first one. This is a problem The second variable named `state` shadows the first one. This is a problem