diff --git a/README.md b/README.md index beb6965f..8b02a59e 100644 --- a/README.md +++ b/README.md @@ -6823,7 +6823,7 @@ You can use the break instruction to quit the block (the clear\_code will be executed) or you can use exception. -##### M\_CHAIN\_INIT(init\_code, clear\_code) +##### M\_CHAIN\_INIT(name, init\_code, clear\_code) This macro executes 'init\_code' then registers the execution of 'clear\_code' if an exception is triggered @@ -6831,7 +6831,7 @@ until the further closing brace of the next block of instruction. init\_code and clear\_code shall be a valid expression. If exception are not enabled, it simply executes 'init\_code'. -There shall be at most one M\CHAIN\_INIT macro per line of source code. +name shall a unique identifier in the current block. It can be chained multiple times to register multiple registrations. Therefore it enables support for chaining @@ -6849,8 +6849,8 @@ Example: void struct_init_set(struct_t d, struct_t s) { - M_CHAIN_INIT(string_init_set(d->s1, s->s1), string_clear(d->s1) ) - M_CHAIN_INIT(string_init_set(d->s2, s->s2), string_clear(d->s2) ) { + M_CHAIN_INIT(s1, string_init_set(d->s1, s->s1), string_clear(d->s1) ) + M_CHAIN_INIT(s2, string_init_set(d->s2, s->s2), string_clear(d->s2) ) { d->num = s->num; } } diff --git a/m-core.h b/m-core.h index 7f20d040..03c9df51 100644 --- a/m-core.h +++ b/m-core.h @@ -4392,13 +4392,13 @@ m_core_parse2_enum (const char str[], const char **endptr) The clear code is only executed on exception. USAGE: void init_function(struct_t s) { - M_CHAIN_INIT(string_init(s->str), string_clear(s->str)) { + M_CHAIN_INIT(name, string_init(s->str), string_clear(s->str)) { // Rest of initialization code } } */ -#define M_CHAIN_INIT(init, clear) \ - M_CHAIN_INIT_INTERNAL(M_C(m_var_, __LINE__), init, clear) +#define M_CHAIN_INIT(name, init, clear) \ + M_CHAIN_INIT_INTERNAL(M_C(m_var_, name), init, clear) #define M_CHAIN_INIT_INTERNAL(cont, init, clear) \ for(bool cont = true; cont; cont = false) \ @@ -4512,10 +4512,6 @@ m_core_parse2_enum (const char str[], const char **endptr) ) #define M_INIT_EMPLACE_VAI2_FUNC(pair, a) \ M_INIT_EMPLACE_VAI3_FUNC(M_PAIR_1 pair, M_PAIR_2 pair, a) - -/* We first push a raw new item, and then we get back its pointer using _back. - _back (contrary to _push_raw) has no side effect, and so is safe to be used - in a macro */ #define M_INIT_EMPLACE_VAI3_FUNC(d, op, a) \ ( \ M_IF(M_PARENTHESIS_P(a)) \ diff --git a/tests/test-mtry.c b/tests/test-mtry.c index f2f84c8c..881d2301 100644 --- a/tests/test-mtry.c +++ b/tests/test-mtry.c @@ -469,8 +469,8 @@ volatile int g_throw = 0; static void struct_init(struct_t x) { - M_CHAIN_INIT(testobj_init(x->o1), testobj_clear(x->o1) ) - M_CHAIN_INIT(testobj_init(x->o2), testobj_clear(x->o2) ) { + M_CHAIN_INIT(o1, testobj_init(x->o1), testobj_clear(x->o1) ) + M_CHAIN_INIT(o2, testobj_init(x->o2), testobj_clear(x->o2) ) { x->num = 0; if (++g_flow == g_throw) M_THROW(1); } @@ -478,10 +478,10 @@ static void struct_init(struct_t x) static void struct_init_set(struct_t x, const struct_t y) { - M_CHAIN_INIT(testobj_init_set(x->o1, y->o1), testobj_clear(x->o1) ) { + M_CHAIN_INIT(o1, testobj_init_set(x->o1, y->o1), testobj_clear(x->o1) ) { // Throw within the constructor (object partially constructed) if (++g_flow == g_throw) M_THROW(1); - M_CHAIN_INIT(testobj_init_set(x->o2, y->o2), testobj_clear(x->o2) ) { + M_CHAIN_INIT(o2, testobj_init_set(x->o2, y->o2), testobj_clear(x->o2) ) { x->num = y->num; if (++g_flow == g_throw) M_THROW(1); }