Недавно я наткнулся на расширение gcc, которое я нашел довольно полезным: __attribute__(cleanup)
В принципе, это позволяет назначить вызов очистки локальной переменной в момент выхода из области. Например, в следующем разделе кода вся память должна поддерживаться и обрабатываться явно в любом случае во время вызова foo
.
void foo() {
char * buff = ...; /* some memory allocation */
char * buff2 = 0, * buff3 = 0;
if (! buff) {
return;
} else {
buff2 = ...; /* memory allocation */
if (! buff2) {
goto clean_exit;
} else {
/* ... and so on ... */
}
}
clean_exit:
free (buff);
free (buff2);
free (buff3);
}
Однако, используя расширение, которое можно уменьшить до
#define clean_pchar_scope __attribute__((cleanup(pchar_free)))
void pchar_free (char ** c) { free (*c); }
void foo () {
char * buff clean_pchar_scope = ...; /* some memory allocation */
char * buff2 clean_pchar_scope = 0, * buff3 clean_pchar_scope = 0;
if (! buff)
return;
buff2 = ...; /* memory allocation */
if (! buff2)
return;
/* and so on */
}
Теперь вся память восстанавливается на основе области без использования вложенных конструкций if/else или goto в сочетании с секцией освобождения консолидированной памяти функции. Я понимаю, что использование goto можно было бы избежать там для более вложенной конструкции if/else (так что, пожалуйста, никаких священных войн на goto...), и что этот пример надуман, но факт остается фактом: это может быть довольно полезная функция.
К сожалению, насколько я знаю, это спецификация gcc. Меня интересуют любые переносные способы сделать то же самое (если они даже существуют). Кто-нибудь имел опыт в этом с чем-то отличным от gcc?
EDIT: Кажется, что переносимость не в игре. Учитывая, что есть ли способ сделать это за пределами gcc-пространства? Кажется приятной особенностью быть gcc-специфической...