Блоки (расширение языка 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 являются обычными указателями функций и могут использоваться непосредственно с существующим кодом.

Смотрите также

Рекомендации

  1. ^ а б "Темы программирования блоков". Разработчик Apple. Apple Inc.. Получено 2011-03-08.
  2. ^ https://code.google.com/p/plblocks/
  3. ^ "Гранд Сентрал Диспетч" (PDF) (Краткое техническое описание). яблоко. 2009-09-03. Архивировано из оригинал (PDF) на 2009-09-20. Получено 9 июня, 2009.
  4. ^ Сиракуза, Джон (1 сентября 2009 г.). «Mac OS X 10.6 Snow Leopard: обзор Ars Technica: блоки». Ars Technica.
  5. ^ Мунши, Афтаб, изд. (13.07.2013). «Спецификация OpenCL C. Версия 2.0. Версия документа 11» (PDF). Рабочая группа Khronos OpenCL. п. 173. Архивировано с оригинал (PDF) на 2013-11-05. Получено 2013-07-23.
  6. ^ Бенгтссон, Иоахим. «Программирование с помощью блоков C на устройствах Apple». Архивировано из оригинал на 2017-11-15. Получено 2009-09-17.
  7. ^ "mackyle / blocksruntime: автономная среда выполнения блоков". Получено 15 января 2020.
  8. ^ «Вложенные функции: использование коллекции компиляторов GNU (GCC)».

внешняя ссылка