Блоки () — расширение языков программирования C, C++, Objective-C, не описанное в стандартах этих языков и созданное фирмой Apple. Расширение позволяет создавать замыкания, используя лямбда-подобный синтаксис.

«Блоки» были созданы с целью облегчения написания приложений для платформы Grand Central DispatchApple Technical Brief on Grand Central Dispatch , но могут использоваться и на других платформах. Apple реализовала «блоки» в собственной ветке компилятора GCC. Для компиляторов LLVM создана библиотека времени исполнения.

«Блоки» похожи на функции: могут принимать аргументы и возвращать значения; могут иметь локальные переменные; могут вызываться, как и обычные функции; имеют адреса, которые могут использоваться как обычные указатели на функцию (то есть, указатели на «блоки» могут храниться в переменных, могут передаваться в функции).

В отличие от функций: внутри «блоков» могут использоваться переменные, доступные функции, внутри которой создавался «блок».

Для работы с блоками компилятор генерирует дополнительный код. В процессе выполнения программы для каждого создаваемого блока этот код создаёт скрытый объект. Объект содержит следующие поля: ссылка на код блока; значения локальных переменных, доступных функции, внутри которой блок был создан.

Чтобы сообщить компилятору о том, что в переменной будет храниться адрес «блока» (а не обычной функции) следует использовать особое ключевое слово. Ключевое слово не требуется, если «блок» и переменная находятся в одной области видимости.

Пример В следующем примере функция создаёт блок и возвращает указатель на него. #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

См. также Замыкание Лямбда-исчисление Лямбда-выражения XNU

Ссылки

Категория:Параллельные вычисления Категория:Программное обеспечение Apple Категория:Си (язык программирования)