Tweak wording in the macros guide
This commit is contained in:
parent
1804242a2d
commit
df0865754e
1 changed files with 19 additions and 10 deletions
|
@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern.
|
||||||
|
|
||||||
## Repetition
|
## Repetition
|
||||||
|
|
||||||
The repetition behavior can seem somewhat magical, especially when multiple
|
The repetition operator follows two principal rules:
|
||||||
names are bound at multiple nested levels of repetition. The two rules to keep
|
|
||||||
in mind are:
|
|
||||||
|
|
||||||
1. the behavior of `$(...)*` is to walk through one "layer" of repetitions, for
|
1. `$(...)*` walks through one "layer" of repetitions, for all of the `$name`s
|
||||||
all of the `$name`s it contains, in lockstep, and
|
it contains, in lockstep, and
|
||||||
2. each `$name` must be under at least as many `$(...)*`s as it was matched
|
2. each `$name` must be under at least as many `$(...)*`s as it was matched
|
||||||
against. If it is under more, it'll be duplicated, as appropriate.
|
against. If it is under more, it'll be duplicated, as appropriate.
|
||||||
|
|
||||||
This baroque macro illustrates the duplication of variables from outer
|
This baroque macro illustrates the duplication of variables from outer
|
||||||
repetition levels.
|
repetition levels.
|
||||||
|
@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a
|
||||||
more" match. Both forms optionally include a separator, which can be any token
|
more" match. Both forms optionally include a separator, which can be any token
|
||||||
except `+` or `*`.
|
except `+` or `*`.
|
||||||
|
|
||||||
|
This system is based on
|
||||||
|
"[Macro-by-Example](http://www.cs.indiana.edu/ftp/techreports/TR206.pdf)"
|
||||||
|
(PDF link).
|
||||||
|
|
||||||
# Hygiene
|
# Hygiene
|
||||||
|
|
||||||
Some languages implement macros using simple text substitution, which leads to
|
Some languages implement macros using simple text substitution, which leads to
|
||||||
|
@ -273,19 +275,26 @@ macro, using [a GNU C extension] to emulate Rust's expression blocks.
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
This looks reasonable, but watch what happens in this example:
|
Here's a simple use case that goes terribly wrong:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
const char *state = "reticulating splines";
|
const char *state = "reticulating splines";
|
||||||
LOG(state);
|
LOG(state)
|
||||||
```
|
```
|
||||||
|
|
||||||
The program will likely segfault, after it tries to execute
|
This expands to
|
||||||
|
|
||||||
```text
|
```text
|
||||||
printf("log(%d): %s\n", state, state);
|
const char *state = "reticulating splines";
|
||||||
|
int state = get_log_state();
|
||||||
|
if (state > 0) {
|
||||||
|
printf("log(%d): %s\n", state, state);
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The second variable named `state` shadows the first one. This is a problem
|
||||||
|
because the print statement should refer to both of them.
|
||||||
|
|
||||||
The equivalent Rust macro has the desired behavior.
|
The equivalent Rust macro has the desired behavior.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue