Skip to content

Commit

Permalink
Rollup merge of rust-lang#39775 - mina86:master, r=steveklabnik
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
frewsxcv committed Feb 16, 2017
2 parents 4d6019d + b6a1618 commit ef45eca
Showing 1 changed file with 6 additions and 8 deletions.
14 changes: 6 additions & 8 deletions src/doc/book/src/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ef45eca

Please sign in to comment.