@@ -189,14 +189,12 @@ shorthand for a data type could be valid as either an expression or a pattern.
189
189
190
190
## Repetition
191
191
192
- The repetition behavior can seem somewhat magical, especially when multiple
193
- names are bound at multiple nested levels of repetition. The two rules to keep
194
- in mind are:
192
+ The repetition operator follows two principal rules:
195
193
196
- 1 . the behavior of ` $(...)* ` is to walk through one "layer" of repetitions, for
197
- all of the ` $name ` s it contains, in lockstep, and
194
+ 1 . ` $(...)* ` walks through one "layer" of repetitions, for all of the ` $name ` s
195
+ it contains, in lockstep, and
198
196
2 . each ` $name ` must be under at least as many ` $(...)* ` s as it was matched
199
- against. If it is under more, it'll be duplicated, as appropriate.
197
+ against. If it is under more, it'll be duplicated, as appropriate.
200
198
201
199
This baroque macro illustrates the duplication of variables from outer
202
200
repetition levels.
@@ -226,6 +224,10 @@ That's most of the matcher syntax. These examples use `$(...)*`, which is a
226
224
more" match. Both forms optionally include a separator, which can be any token
227
225
except ` + ` or ` * ` .
228
226
227
+ This system is based on
228
+ "[ Macro-by-Example] ( http://www.cs.indiana.edu/ftp/techreports/TR206.pdf ) "
229
+ (PDF link).
230
+
229
231
# Hygiene
230
232
231
233
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.
273
275
})
274
276
```
275
277
276
- This looks reasonable, but watch what happens in this example :
278
+ Here's a simple use case that goes terribly wrong :
277
279
278
280
``` text
279
281
const char *state = "reticulating splines";
280
- LOG(state);
282
+ LOG(state)
281
283
```
282
284
283
- The program will likely segfault, after it tries to execute
285
+ This expands to
284
286
285
287
``` text
286
- printf("log(%d): %s\n", state, state);
288
+ const char *state = "reticulating splines";
289
+ int state = get_log_state();
290
+ if (state > 0) {
291
+ printf("log(%d): %s\n", state, state);
292
+ }
287
293
```
288
294
295
+ The second variable named ` state ` shadows the first one. This is a problem
296
+ because the print statement should refer to both of them.
297
+
289
298
The equivalent Rust macro has the desired behavior.
290
299
291
300
``` rust
0 commit comments