Comments 5
Хороший пример использования этого атрибута – critical section в атмеловской либе для atmega/attiny.
С
Пример:
Вывод:
А вот clang отслеживает наличие на границе области видимости выполняющейся cleanup-функции, зависящей от переменной
__attribbute__(( cleanup(...) ))
могут быть нюансы, связанные с повторным заходом в область видимости.Пример:
int main(void)
{
{
struct Obj *test __attribute__(( cleanup(Obj_cleanup) )) = calloc(1, sizeof(struct Obj));
fprintf(stdout, "Obj allocated at %p\n", (void*)test);
fprintf(stdout, "Quitting the test scope...\n");
goto main__sub1;
main__exit:
return 0;
} // <-- Obj_cleanup is executed here twice, even though the control flow passes the 'test' definition only once
main__sub1:
fprintf(stdout, "The test scope has been quit.\n");
goto main__exit;
}
Вывод:
Obj allocated at 00000000005F6880
Quitting the test scope…
Obj_cleanup() for 00000000005F6880
The test scope has been quit.
Obj_cleanup() for 00000000005F6880
А вот clang отслеживает наличие на границе области видимости выполняющейся cleanup-функции, зависящей от переменной
test
, и отказывается компилировать такой код.int *ptr_one = (int *)malloc(sizeof(int));
- Не стоит преобразовывать явно возвращаемое значение malloc — это Си, а не Си++, и здесь void * приводится к любому указателю: void * для этого и придуман.
- Не стоит в данной конструкции использовать sizeof(int), конструкция sizeof(*ptr_one) уменьшает число точек отказа при поддержке кода.
Например, при смене типа переменной (int * на long * — как вариант), если выполнить пункты выше — вся конструкция останется валидной. (А лучше, если здесь будет указатель на структурный объект.)
Если оставить как есть, то рано или поздно кто-нибудь да забудет исправить размер выделяемой памяти, а явное преобразование типа запретит умному компилятору выдать предупреждение об этом (так как явное преобразование — это «делай как я сказал» в Си).
Sign up to leave a comment.
Атрибут cleanup