|
Metalang99 1.13.3
Full-blown preprocessor metaprogramming
|
Statement chaining. More...

Go to the source code of this file.
Macros | |
| #define | ML99_INTRODUCE_VAR_TO_STMT(...) ML99_PRIV_INTRODUCE_VAR_TO_STMT_INNER(__VA_ARGS__) |
| A statement chaining macro that introduces several variable definitions to a statement right after its invocation. | |
| #define | ML99_INTRODUCE_NON_NULL_PTR_TO_STMT(ty, name, init) ML99_PRIV_SHADOWS(for (ty *name = (init); name != 0; name = 0)) |
The same as ML99_INTRODUCE_VAR_TO_STMT but deals with a single non-NULL pointer. | |
| #define | ML99_CHAIN_EXPR_STMT(expr) |
A statement chaining macro that executes an expression statement derived from expr right before the next statement. | |
| #define | ML99_CHAIN_EXPR_STMT_AFTER(expr) |
The same as ML99_CHAIN_EXPR_STMT but executes expr after the next statement. | |
| #define | ML99_SUPPRESS_UNUSED_BEFORE_STMT(expr) ML99_CHAIN_EXPR_STMT((void)expr) |
| A statement chaining macro that suppresses the "unused X" warning right before a statement after its invocation. | |
Statement chaining.
This module exports a bunch of so-called statement chaining macros: they expect a statement right after their invocation, and moreover, an invocation of such a macro with a statement afterwards altogether form a single statement.
How can this be helpful? Imagine you are writing a macro with the following syntax:
Then MY_MACRO must expand to a statement prefix, i.e., something that expects a statement after itself. One possible solution is to make MY_MACRO expand to a sequence of statement chaining macros like this:
Here ML99_INTRODUCE_VAR_TO_STMT accepts the statement formed by ML99_CHAIN_EXPR_STMT, which, in turn, accepts the next statement and so on, until a caller of MY_MACRO specifies the final statement, thus completing the chain.
| #define ML99_CHAIN_EXPR_STMT | ( | expr | ) |
A statement chaining macro that executes an expression statement derived from expr right before the next statement.
Top-level break/continue inside a user-provided statement are prohibited.
| #define ML99_CHAIN_EXPR_STMT_AFTER | ( | expr | ) |
The same as ML99_CHAIN_EXPR_STMT but executes expr after the next statement.
| #define ML99_INTRODUCE_NON_NULL_PTR_TO_STMT | ( | ty, | |
| name, | |||
| init | |||
| ) | ML99_PRIV_SHADOWS(for (ty *name = (init); name != 0; name = 0)) |
The same as ML99_INTRODUCE_VAR_TO_STMT but deals with a single non-NULL pointer.
In comparison with ML99_INTRODUCE_VAR_TO_STMT, this macro generates a little less code. It introduces a pointer to ty identified by name and initialised to init.
Top-level break/continue inside a user-provided statement are prohibited.
init is guaranteed to be executed only once. | #define ML99_INTRODUCE_VAR_TO_STMT | ( | ... | ) | ML99_PRIV_INTRODUCE_VAR_TO_STMT_INNER(__VA_ARGS__) |
A statement chaining macro that introduces several variable definitions to a statement right after its invocation.
Variable definitions must be specified as in the first clause of the for-loop.
Top-level break/continue inside a user-provided statement are prohibited.
| #define ML99_SUPPRESS_UNUSED_BEFORE_STMT | ( | expr | ) | ML99_CHAIN_EXPR_STMT((void)expr) |
A statement chaining macro that suppresses the "unused X" warning right before a statement after its invocation.
Top-level break/continue inside a user-provided statement are prohibited.
ML99_CHAIN_EXPR_STMT((void)expr) instead.