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

Одной из, скажем так, “нетрадиционных” возможностей, которые предоставляет 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 должны иметь осмысленное значение.

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Yandex.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Google Bookmarks
  • Писали
  • СМИ 2
  • Моё Место
  • 100 Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - IN.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA
  • Slashdot
  • Magnolia
  • Blogmarks
  • Current
  • Meneame
  • Oknotizie
  • Diigo
  • Funp
  • Hugg
  • Dealspl.us
  • N4G
  • Mister Wong
  • Faves
  • Yigg
  • Fresqui
  • Care2
  • Kirtsy
  • Sphinn
  • SaveThis.ru

Связанные записи

2
Июнь
2009

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

  1. Nadyunya says:

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

Подписаться на RSS-ленту комментариев к статье «GCC: освобождение ресурсов для ленивых» Trackback URL: http://blog.sjinks.org.ua/c-cpp/554-gcc-disposing-of-resources-for-lazy-people/trackback/

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

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

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

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