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. More... | |
#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. More... | |
#define | ML99_CHAIN_EXPR_STMT(expr) |
A statement chaining macro that executes an expression statement derived from expr right before the next statement. More... | |
#define | ML99_CHAIN_EXPR_STMT_AFTER(expr) |
The same as ML99_CHAIN_EXPR_STMT but executes expr after the next statement. More... | |
#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. More... | |
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.