I'm trying to create a 'C' macro that will define and initialize static data. 

For example:

    STATIC_CONST_STRUCT
    (
        A, a, 
        MEMBER_DATA(CONST_STR, a, "Hello, a")
        MEMBER_DATA(CONST_STR, b, "Hello, b")
        MEMBER_STRUCT
        (
            C, c, 
            MEMBER_DATA(CONST_STR, d, "Hello, d")
            MEMBER_DATA(CONST_INT, e, 1)
        )
    );

Would cause the 'C' preprocessor to create:

    static const struct A
    {
        CONST_STR a;
        CONST_STR b;
        struct C
        {
            CONST_STR d;
            CONST_INT e;
        } c;
    } =
    {"Hello, a", "Hello, b", {"Hello, d", 1}};

If I could use C++, this would be easy, but I'm using 'C' and it would be very helpful to have the initialization along with the declaration. 

I can't quite figure out how to make this work. My macros stop expanding. I suspect the recursive nature of the problem having an arbitrarily deep nesting is why. If it helps, I do have a maximum depth for the nesting. 

I've tried reading the docs and learn more about recursion, but I can't seem to find a solution. I suspect I'm close.

Here's what I have so far (not claiming this is a good solution, so feel free to suggest anything that would make this better):

    #define MEMBER_DATA_TAG 0
    #define MEMBER_STRUCT_TAG 1
   
    #define MEMBER_TAG(MEMBER) BOOST_PP_SEQ_ELEM(0, MEMBER)
   
    #define MEMBER_DATA_TYPE(MEMBER_DATA) BOOST_PP_SEQ_ELEM(1, MEMBER_DATA)
    #define MEMBER_DATA_NAME(MEMBER_DATA) BOOST_PP_SEQ_ELEM(2, MEMBER_DATA)
    #define MEMBER_DATA_VALUE(MEMBER_DATA) BOOST_PP_SEQ_ELEM(3, MEMBER_DATA)
   
    #define MEMBER_STRUCT_TYPE(MEMBER_STRUCT) BOOST_PP_SEQ_ELEM(1, MEMBER_STRUCT)
    #define MEMBER_STRUCT_NAME(MEMBER_STRUCT) BOOST_PP_SEQ_ELEM(2, MEMBER_STRUCT)
    #define MEMBER_STRUCT_MEMBER_SEQ(MEMBER_STRUCT) BOOST_PP_SEQ_ELEM(3, MEMBER_STRUCT)
   
    #define MEMBER_DATA(TYPE, NAME, VALUE) ((MEMBER_DATA_TAG)(TYPE)(NAME)(VALUE))
    #define MEMBER_STRUCT(TYPE, NAME, MEMBER_SEQ) ((MEMBER_STRUCT_TAG)(TYPE)(NAME)(MEMBER_SEQ))
   
    #define IS_MEMBER_STRUCT(MEMBER_SEQ_ELEM) BOOST_PP_EQUAL(MEMBER_TAG(MEMBER_SEQ_ELEM), MEMBER_STRUCT_TAG)
   
    #define MEMBER_STRUCT_DECLARE(TYPE, NAME, MEMBER_SEQ)                            \
        struct TYPE                                                                  \
        {                                                                            \
            BOOST_PP_SEQ_FOR_EACH(MEMBER_ELEM_DECLARE, BOOST_PP_EMPTY(), MEMBER_SEQ) \
        } NAME
   
    #define MEMBER_ELEM_DECLARE(_r, _data, MEMBER_SEQ_ELEM) \
        BOOST_PP_IIF                                        \
        (                                                   \
            IS_MEMBER_STRUCT(MEMBER_SEQ_ELEM),              \
            MEMBER_STRUCT_DECLARE                           \
            (                                               \
                MEMBER_STRUCT_TYPE(MEMBER_SEQ_ELEM),        \
                MEMBER_STRUCT_NAME(MEMBER_SEQ_ELEM),        \
                MEMBER_STRUCT_MEMBER_SEQ(MEMBER_SEQ_ELEM)   \
            ),                                              \
            MEMBER_DATA_DECLARE                             \
            (                                               \
                MEMBER_DATA_TYPE(MEMBER_SEQ_ELEM),          \
                MEMBER_DATA_NAME(MEMBER_SEQ_ELEM),          \
                MEMBER_DATA_VALUE(MEMBER_SEQ_ELEM)          \
            )                                               \
        );
   
    #define MEMBER_DATA_DECLARE(TYPE, NAME, VALUE) TYPE NAME
   
    #define MEMBER_VALUE_INIT(MEMBER_SEQ) \
        BOOST_PP_SEQ_FOR_EACH_I(MEMBER_VALUE_INIT_DECLARE, BOOST_PP_EMPTY(), MEMBER_SEQ);
   
    #define MEMBER_VALUE_INIT_DECLARE(_r, _data, i, MEMBER_SEQ_ELEM) \
        BOOST_PP_COMMA_IF(i)                                         \
        BOOST_PP_IIF                                                 \
        (                                                            \
            IS_MEMBER_STRUCT(MEMBER_SEQ_ELEM),                       \
            {MEMBER_VALUE_INIT(MEMBER_SEQ_ELEM)},                    \
            MEMBER_DATA_VALUE(MEMBER_SEQ_ELEM)                       \
        )
   
    #define STATIC_CONST_STRUCT(TYPE, NAME, MEMBER_SEQ)              \
        static const MEMBER_STRUCT_DECLARE(TYPE, NAME, MEMBER_SEQ) = \
        {                                                            \
             MEMBER_VALUE_INIT(MEMBER_SEQ)                           \
        }

Thanks.

--

"лось и белка"