GCC: освобождение ресурсов для ленивых

Пример использования атрибутов переменных

Одной из, скажем так, «нетрадиционных» возможностей, которые предоставляет , являются атрибуты типов, переменных и функций.

Я хочу рассказать об одном из них — а именно, отвечающем за удаление использованных ресурсов.

Замечания по переносимости: использование конструкций, характерных для конкретного компилятора — не всегда хорошая идея, особенно, если Вы пишите переносимый код. Но очень удобно, если Вы знаете, что код всегда будет компилироваться конкретным компилятором (в нашем случае — gcc).

Что же это за магическая конструкция, позволяющая автоматом освобождать ресурсы?

А конструкция это такая:

[-]
View Code C
type variable __attribute__((cleanup(function)));

Функция function вызывается, когда переменная variable уходит из области видимости. Функция принимает в качестве параметра указатель на тип, совместимый с переменной (type*). Значение, возвращаемое функцией, игнорируется. Если функция завершается ненормально (например, вызывая исключение), дальнейшее поведение программы не определено.

Данный атрибут применим только к локальным переменным; его нельзя применять к параметрам или статическим переменным.

Использование данной конструкции найдёт почитателей среди противников goto: если в функции есть несколько точек выхода (операторов return), в каждой из которых нужно освобождать ресурсы, это самое то :-)

При известной смекалке эту конструкцию можно использовать для эмуляции tryfinally.

Пример:

[-]
View Code C
void free_char_array(char** x)
{
    if (x && *x) free(*x);
}

void func(void)
{
    char* a __attribute__((cleanup(free_char_array))) = NULL;
    char* b __attribute__((cleanup(free_char_array))) = NULL;
    char* c __attribute__((cleanup(free_char_array))) = NULL;

    a = (char*)malloc(104857600);
    if (!a) return;
    b = (char*)malloc(104857600);
    if (!b) return;
    c = (char*)malloc(104857600);
    if (!c) return;
}

Прелесть использования конструкции состоит в том, что перед return не надо освобождать ресурсы — компилятор автоматически поместит необходимый код (как говорил один преподаватель, не нужно насиловать себе мозг, для этого есть компилятор). Недостаток заключается в том, что в любой точке выхода компилятор вызовет процедуру очистки для всех объявленных переменных (которые выходят из области видимости) с атрибутом cleanup. То есть, если выход осуществляется после неудачного выделения памяти для переменной a, free_char_array() будет вызвана для всех трёх переменных (a, b, c).

Мораль: переменные с атрибутом cleanup должны иметь осмысленное значение.

Автор: ; опубликовано в: C/C++; метки: C/C++, gcc
2
Июн
2009

RSS Комментарии к статье «GCC: освобождение ресурсов для ленивых» (2)  »

  1. Nadyunya

    спасибо очень помогло

Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.

Оставить комментарий к записи «GCC: освобождение ресурсов для ленивых»

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя

गते गते पारगते पारसंगते बोधि स्वाहा