eĿlipsis
a language independent preprocessor
 
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Loading...
Searching...
No Matches
ellipsis-defer.h File Reference

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.
 

Detailed Description

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.

See also
Defer: a lexical extension of the C grammar

Macro Definition Documentation

◆ break

#define break

break to the next loop or switch statement which is compatible with defer

See also
Defer: a lexical extension of the C grammar
break
defer

◆ continue

#define continue

continue the next loop statement which is compatible with defer

See also
Defer: a lexical extension of the C grammar
continue
defer

◆ defer

#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:

  • The depending statement must be a compound statement, then followed by a ;, thus of the form
    defer { ... something ... };
    #define defer
    Mark the depending compound statement as being deferred until the current compound statement (the anc...
    Definition ellipsis-defer.h:524
  • It must be placed into a compound statement, called its anchor statement. That anchor limits the validity of the defer construct.
  • It must not be hidden inside a 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.
  • There must be no jumps into, out of or across a defer statement. Jumps here are the most general, no goto, longjmp, case or default or other labels when accessed from outside the defer block.
  • The secondary block must be valid in place, only that it is guaranteed to be executed at the very end of the guarded function body or block, respectively.
  • If a compound statement contains several defer statements, these are then executed in the inverse lexicographical order.
  • If a compound statement terminates before a specific defer has been met, the depending secondary block is not executed at all.

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:

  • return from the surrounding function context
  • break for surrounding switches or loops
  • continue for surrounding loops
  • If the top-most compound statement of a non-void function, defer_skip can be used to just terminate this compound statement
See also
Defer: a lexical extension of the C grammar
DEFER_TYPE

◆ DEFER_MODE

#define DEFER_MODE

The mode of the defer feature for the current function.

If 0, we are in a function without defer, if 1 in a void function and if 2 in a function with value return. Otherwise the compilation is erroneous.

Warning
This macro may not be undefined or changed otherwise

◆ defer_return_value

#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.

Warning
This can obviously only be used after the return value has been set, that is after a return statement has been executed. The only points where this is accessible are during deferred statements that are executed after such a return. A good static analyzer should always warn you of possible code paths that try to use this value before it exists.
See also
Defer: a lexical extension of the C grammar
DEFER_TYPE

◆ defer_skip

#define defer_skip

terminate the closest surrounding compound statement with defer statements

If there is no such compound statement a compile time error occurs.

See also
Defer: a lexical extension of the C grammar

◆ DEFER_TYPE

#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.

See also
Defer: a lexical extension of the C grammar

◆ return

#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.

Warning
If defer is included in the unit, using 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.
Remarks
If the function has type 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.
See also
Defer: a lexical extension of the C grammar
DEFER_TYPE
defer_return_value