Блоки (расширение языка C) - Blocks (C language extension)
Блоки являются нестандартным расширением, добавленным Apple Inc. к Лязг реализации C, C ++, и Цель-C языки программирования, использующие лямбда-выражение -подобный синтаксис для создания закрытие на этих языках. Блоки поддерживаются для программ, разработанных для Mac OS X 10.6+ и iOS 4.0+,[1] хотя сторонние среды выполнения позволяют использовать в Mac OS X 10.5 и iOS 2.2+[2] и системы сторонних производителей.
Apple разработала блоки с явной целью облегчить написание программ для Grand Central Dispatch многопоточная архитектура,[3][4] хотя он не зависит от этой архитектуры и может использоваться почти так же, как замыкания на других языках. Apple реализовала блоки как в своей собственной ветке Коллекция компиляторов GNU[1] и в верхнем течении Лязг LLVM передняя часть компилятора. Язык библиотека времени исполнения поддержка блоков также доступна в рамках проекта LLVM. Группа Khronos использует синтаксис блоков для постановки ядер в очередь из ядра, начиная с версии 2.0. OpenCL.[5]
Как и определения функций, блоки могут принимать аргументы и внутренне объявлять собственные переменные. В отличие от обычных определений функций C, их значение может захватывать состояние из окружающего их контекста. Определение блока создает непрозрачное значение, которое содержит как ссылку на код внутри блока, так и снимок текущего состояния локальных переменных стека на момент его определения. Блок может быть позже вызван так же, как указатель функции. Блок может быть назначен переменным, передан функциям и иным образом обработан как обычный указатель на функцию, хотя прикладной программист (или API) должен пометить блок специальным оператором (Block_copy), если он будет использоваться вне области видимости в который был определен.
Учитывая значение блока, код внутри блока может быть выполнен в любое время позже, вызвав его, используя тот же синтаксис, который использовался бы для вызова функции.
Примеры
Простым примером захвата изменяемого состояния в окружающей области является целочисленный диапазон итератор:[6]
/ * блоки-test.c * /#включают <stdio.h>#включают <Block.h>/ * Тип блока, не принимающего ничего, возвращающего int * /typedef int (^IntBlock)();IntBlock MakeCounter(int Начните, int приращение) { __блокировать int я = Начните; возвращаться Block_copy( ^(пустота) { int Ret = я; я += приращение; возвращаться Ret; }); }int основной(пустота) { IntBlock mycounter = MakeCounter(5, 2); printf("Первый звонок:% d п", mycounter()); printf("Второй звонок:% d п", mycounter()); printf("Третий звонок:% d п", mycounter()); / * поскольку он был скопирован, его также необходимо освободить * / Block_release(mycounter); возвращаться 0;}
Скомпилировать и выполнить
$ clang -fblocks блоки-test.c # Mac OS X$ ./a.outПервый звонок: 5Второй звонок: 7Третий звонок: 9
Среда выполнения блоков не является частью библиотеки (библиотек) C, связанных по умолчанию в некоторых системах. В этом случае требуется явная ссылка на эту библиотеку:
$ clang -fblocks блоки-test.c -lBlocksRuntime # Linux
Среда выполнения является частью среды выполнения clang, но иногда не устанавливается вместе с пакетом clang. Доступна автономная среда выполнения, извлеченная из compiler-rt.[7]
Отношение к вложенным функциям GCC
Блоки внешне похожи на GCC расширение C для поддержки лексически ограниченный вложенные функции.[8] Однако вложенные функции GCC, в отличие от блоков, не должны вызываться после выхода из содержащей их области, так как это приведет к неопределенное поведение.
Вложенные функции в стиле GCC в настоящее время используют динамическое создание исполняемого файла. thunks на большинстве архитектур при получении адреса вложенной функции. На большинстве архитектур (включая X86) эти переходники создаются в стеке, что требует пометки исполняемого файла стека. Исполняемые стеки обычно считаются потенциальной дырой в безопасности. Блоки не требуют использования исполняемых преобразователей, поэтому они не разделяют эту слабость. С другой стороны, блоки представляют собой совершенно новый тип указателя, а указатели на вложенные функции в GCC являются обычными указателями функций и могут использоваться непосредственно с существующим кодом.
Смотрите также
- Закрытие (информатика)
- Лексический объем
- Лямбда (программирование)
- Стек спагетти
- Thunk (функциональное программирование)
- XNU
- C ++ 11 (включает «лямбда-выражения»)
Рекомендации
- ^ а б "Темы программирования блоков". Разработчик Apple. Apple Inc.. Получено 2011-03-08.
- ^ https://code.google.com/p/plblocks/
- ^ "Гранд Сентрал Диспетч" (PDF) (Краткое техническое описание). яблоко. 2009-09-03. Архивировано из оригинал (PDF) на 2009-09-20. Получено 9 июня, 2009.
- ^ Сиракуза, Джон (1 сентября 2009 г.). «Mac OS X 10.6 Snow Leopard: обзор Ars Technica: блоки». Ars Technica.
- ^ Мунши, Афтаб, изд. (13.07.2013). «Спецификация OpenCL C. Версия 2.0. Версия документа 11» (PDF). Рабочая группа Khronos OpenCL. п. 173. Архивировано с оригинал (PDF) на 2013-11-05. Получено 2013-07-23.
- ^ Бенгтссон, Иоахим. «Программирование с помощью блоков C на устройствах Apple». Архивировано из оригинал на 2017-11-15. Получено 2009-09-17.
- ^ "mackyle / blocksruntime: автономная среда выполнения блоков". Получено 15 января 2020.
- ^ «Вложенные функции: использование коллекции компиляторов GNU (GCC)».
внешняя ссылка
- «Расширения языка Clang: блоки». LLVM проект. Получено 2013-01-20.
- ""compiler-rt "Библиотека времени выполнения". LLVM проект. Получено 2013-01-20.