Недавно я наткнулся на расширение 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 ...