Блоки (расширение языка Си) (>lktn (jgvonjyuny x[dtg Vn))
Блоки (англ. blocks) — расширение языков программирования C, C++, Objective-C, не описанное в стандартах этих языков и созданное фирмой Apple. Расширение позволяет создавать замыкания, используя лямбда-подобный синтаксис.
«Блоки» были созданы с целью облегчения написания приложений для платформы Grand Central Dispatch[1][2], но могут использоваться и на других платформах. Apple реализовала «блоки» в собственной ветке компилятора GCC. Для компиляторов LLVM создана библиотека времени исполнения.
«Блоки» похожи на функции:
- могут принимать аргументы и возвращать значения;
- могут иметь локальные переменные;
- могут вызываться, как и обычные функции;
- имеют адреса, которые могут использоваться как обычные указатели на функцию (то есть, указатели на «блоки» могут храниться в переменных, могут передаваться в функции).
В отличие от функций:
- внутри «блоков» могут использоваться переменные, доступные функции, внутри которой создавался «блок».
Для работы с блоками компилятор генерирует дополнительный код. В процессе выполнения программы для каждого создаваемого блока этот код создаёт скрытый объект. Объект содержит следующие поля:
- ссылка на код блока;
- значения локальных переменных, доступных функции, внутри которой блок был создан.
Чтобы сообщить компилятору о том, что в переменной будет храниться адрес «блока» (а не обычной функции) следует использовать особое ключевое слово. Ключевое слово не требуется, если «блок» и переменная находятся в одной области видимости.
Пример
[править | править код]В следующем примере[3] функция MakeCounter
создаёт блок и возвращает указатель на него.
#include <stdio.h>
#include <Block.h>
// создание псевдонима для типа «указатель на блок»
typedef int ( ^ IntBlock ) ();
IntBlock MakeCounter ( int start, int increment ) {
__block int i = start;
return Block_copy( ^ {
int ret = i;
i += increment;
return ret;
} );
}
int main () {
IntBlock my_counter = MakeCounter( 5, 2 );
printf( "First call: %d\n", my_counter() );
printf( "Second call: %d\n", my_counter() );
printf( "Third call: %d\n", my_counter() );
// освободить память, выделенную при создании блока для хранения скрытого объекта
Block_release( my_counter );
return 0;
}
Программа напечатает следующее.
First call: 5 Second call: 7 Third call: 9
Команда для компиляции примера с помощью компилятора clang:
clang -fblocks blocks-test.c -lBlocksRuntime
См. также
[править | править код]Ссылки
[править | править код]- ↑ Apple Technical Brief on Grand Central Dispatch Архивировано 12 июня 2009 года.
- ↑ Mac OS X 10.6 Snow Leopard: the Ars Technica review: Blocks . Дата обращения: 29 сентября 2017. Архивировано 9 мая 2012 года.
- ↑ Bengtsson, J., Programming with C Blocks on Apple Devices, Архивировано из оригинала 25 октября 2010, Дата обращения: 31 октября 2009 Источник . Дата обращения: 31 октября 2009. Архивировано из оригинала 25 октября 2010 года.