Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Annex: No Variadic Macros

This section presents an alternative syntax for compilers without variadic macro support.

Sequence Syntax

Most modern compilers support variadic macros (notably, these include GCC, MSVC, and all C++11 compilers). [10] However, in the rare case that programmers need to use this library on a complier without variaidc macros, this library also allows to specify the capture list using a Boost.Preprocessor sequence where tokens are separated by round parenthesis ():

(capture1) (capture2) ... // All compilers.

Instead of the comma-separated list that we have seen so far which requires variadic macros:

capture1, capture2, ... // Only compilers with variadic macros.

For example, the following syntax is accepted on all compilers with and without variadic macros (see also world_seq.cpp and world.cpp):

Boost.Preprocessor Sequence (All Compilers)

Comma-Separated List (Variadic Macros Only)

void world::add_person(person const& a_person) {
    bool commit = false;

    persons_.push_back(a_person);           // (1) direct action
    // Following block is executed when the enclosing scope exits.
    BOOST_SCOPE_EXIT( (&commit) (&persons_) ) {
        if(!commit) persons_.pop_back();    // (2) rollback action
    } BOOST_SCOPE_EXIT_END

    // ...                                  // (3) other operations

    commit = true;                          // (4) disable rollback actions
}

void world::add_person(person const& a_person) {
    bool commit = false;

    persons_.push_back(a_person);           // (1) direct action
    // Following block is executed when the enclosing scope exits.
    BOOST_SCOPE_EXIT(&commit, &persons_) {
        if(!commit) persons_.pop_back();    // (2) rollback action
    } BOOST_SCOPE_EXIT_END

    // ...                                  // (3) other operations

    commit = true;                          // (4) disable rollback actions
}

Note how the same macros accept both syntaxes on compilers with variadic macros and only the Boost.Preprocessor sequence syntax on compilers without variadic macros. Older versions of this library used to only support the Boost.Preprocessor sequence syntax so this syntax is supported also for backward compatibility. However, in the current version of this library and on compilers with variadic macros, the comma-separated syntax is preferred because it is more readable.

Finally, an empty capture list is always specified using void on compilers with and without variaidc macros (see also world_void.cpp):

struct world_t {
    std::vector<person> persons;
    bool commit;
} world; // Global variable.

void add_person(person const& a_person) {
    world.commit = false;
    world.persons.push_back(a_person);

    BOOST_SCOPE_EXIT(void) { // No captures.
        if(!world.commit) world.persons.pop_back();
    } BOOST_SCOPE_EXIT_END

    // ...

    world.commit = true;
}

Examples

For reference, the following is a list of most of the examples presented in this documentation reprogrammed using the Boost.Preprocessor sequence syntax instead of comma-separated lists (in alphabetic order):

Files

same_line_seq.cpp

scope_guard_seq.cpp

try_catch_seq.cpp

world_checkpoint_all_seq.cpp

world_checkpoint_seq.cpp

world_this_seq.cpp

world_tpl_seq.cpp



[10] A C++ compiler does not support variadic macros if the Boost.Config macro BOOST_NO_CXX11_VARIADIC_MACROS is defined for that compiler.


PrevUpHomeNext