Implement a defer feature to postpone execution of specific blocks. More...
Go to the source code of this file.
Macros | |
#define | break |
break to the next loop or switch statement which is compatible with defer | |
#define | continue |
continue the next loop statement which is compatible with defer | |
#define | defer |
Mark the depending compound statement as being deferred until the current compound statement (the anchor) terminates. | |
#define | DEFER_MODE |
The mode of the defer feature for the current function. | |
#define | defer_return_value |
access the return value of a function from within a defer statement | |
#define | defer_skip |
terminate the closest surrounding compound statement with defer statements | |
#define | DEFER_TYPE(...) |
Provide the return type to a function context that uses the defer feature. | |
#define | return |
Return from a function. If it has active defer clauses, unwind these. | |
Implement a defer feature to postpone execution of specific blocks.
Using this header imposes that all loop and switch statements have a compound statement as secondary block.
#define defer |
Mark the depending compound statement as being deferred until the current compound statement (the anchor) terminates.
You may use this construct only in a constrained setting:
;
, thus of the form if
, switch
or loop statement without using a compound statement. So in particular the defer itself can not be conditioned. If you are tempted to do this, usually you should put the condition (if
statement) inside the defer, not in front. This implementation complains about all loop or switch bodies that are not compound statements.goto
, longjmp
, case
or default
or other labels when accessed from outside the defer block.The anchor should not contain preliminary entries or exits by
switch
cases, including default
.goto
into or out of the compound statement.longjmp
out of the compound statement.exit
or quick_exit
.If any of these is used, the cleanup code of pending defer statements is not executed and thus the state is not clean.
Several preliminary exits from the compound statement are possible, though:
switches
or loopsvoid
function, defer_skip can be used to just terminate this compound statement#define DEFER_MODE |
#define defer_return_value |
access the return value of a function from within a defer statement
This can be used in particular in the very first defer of a non-void
function to control a non-regular jump out of the function.
#define defer_skip |
terminate the closest surrounding compound statement with defer statements
If there is no such compound statement a compile time error occurs.
#define DEFER_TYPE | ( | ... | ) |
Provide the return type to a function context that uses the defer feature.
The argument list has to contain a type name that is compatible with the return type of the function, or be empty if that return type is void
.
This must be used just after the opening brace of the function body. The body shall not contain preliminary entries or exits by
longjmp
out of the body.exit
or quick_exit
unless they are located before or within the first lexicographical defer.
If any of these is used in other places, the cleanup code of pending defer statements is not executed and thus the state is not clean.
return constitutes a preliminary exit from the body and guarantees that all active defer statements are executed.
#define return |
Return from a function. If it has active defer clauses, unwind these.
If there is no visible defer statement this macro just resolves to the normal keyword return.
If there is a visible defer, the current list of deferred statements is executed in reverse order. If also a return type had been specified by means of DEFER_TYPE, before unwinding the return expression is executed and its value is stored in a temporary variable. That value can be read by using defer_return_value.
return
with a return expression must first use DEFER_TYPE to instruct eĿlipsis about the return type of the function. Otherwise, the compilation will be on error.void
, no special precautions are necessary and both, return without a return expression and falling off at the end of the function body, should work as usual.