Blocos (extensão da linguagem C) - Blocks (C language extension)

Blocos são uma extensão não-padrão adicionado por Apple Inc. para Clang implementações do 's C , C ++ e Objective-C linguagens de programação que usa uma expressão lambda -como sintaxe para criar fechamentos dentro dessas línguas. Blocos são suportados para programas desenvolvidos para Mac OS X 10.6+ e iOS 4.0+, embora os tempos de execução de terceiros permitem o uso em Mac OS X 10.5 e iOS 2.2+ e sistemas não-Apple.

A Apple projetou blocos com o objetivo explícito de torná-lo mais fácil escrever programas para o o Grand Central Dispatch arquitetura enfiar, embora seja independente da arquitetura e pode ser usado em quase da mesma maneira como fechamentos em outros idiomas. A Apple implementou blocos tanto em seu próprio ramo da GNU Compiler Collection e no upstream Clang LLVM final compilador frente. Idioma biblioteca runtime suporte para blocos também está disponível como parte do projeto LLVM. O grupo Kronos utiliza blocos de sintaxe para enfileirar os kernels de dentro como grãos de versão 2.0 do OpenCL .

Como definições de funções, blocos podem ter argumentos, e declarar suas próprias variáveis ​​internamente. Ao contrário de definições de função C comum, o seu valor pode capturar o estado de seu contexto circundante. Uma definição de bloco produz um valor opaca que contém uma referência ao código no interior do bloco e uma imagem do estado actual de variáveis ​​locais pilha no momento da sua definição. O bloco pode ser mais tarde chamados da mesma maneira como um ponteiro de função. O bloco pode ser atribuído às variáveis, passados ​​para as funções, e tratadas de outro modo, como um ponteiro função normal, embora o programador da aplicação (ou a API) deve marcar o bloco com um operador especial (Block_copy) se é para ser utilizado fora do âmbito em que foi definido.

Dado um valor de bloco, o código dentro do bloco pode ser executado em qualquer momento posterior, chamando-o, usando a mesma sintaxe que seria usado para chamar uma função.

Exemplos

Um exemplo simples que captura estado mutável no âmbito circundante é um intervalo inteiro iteração :

  • blocos-test.c
#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)();

IntBlock MakeCounter(int start, int increment) {
	__block int i = start;
	
	return Block_copy( ^(void) {
		int ret = i;
		i += increment;
		return ret;
	});
	
}

int main(void) {
	IntBlock mycounter = MakeCounter(5, 2);
	printf("First call: %d\n", mycounter());
	printf("Second call: %d\n", mycounter());
	printf("Third call: %d\n", mycounter());
	
	/* because it was copied, it must also be released */
	Block_release(mycounter);
	
	return 0;
}

Compilar e executar

$ clang -fblocks blocks-test.c # Mac OS X
$ # clang -fblocks blocks-test.c -lBlocksRuntime # Linux
$ ./a.out
First call: 5
Second call: 7
Third call: 9

Relação com funções GCC aninhados

Blocos têm uma semelhança superficial com a GCC extensão de C para apoiar 's escopo léxico funções aninhadas . No entanto, funções aninhadas do GCC, ao contrário de blocos, não deve ser chamado após o escopo contendo saiu, como que resultaria em um comportamento indefinido .

Funções aninhadas GCC de estilo atualmente usam criação dinâmica de executáveis thunks na maioria das arquiteturas quando se toma o endereço da função aninhada. Na maioria das arquiteturas (incluindo X86), estes thunks são criados na pilha, o que exige a marcação do executável pilha. Pilhas executáveis são geralmente considerada uma potencial falha de segurança. Blocos não requerem o uso de thunks executáveis, então eles não compartilham essa fraqueza. Por outro lado, os blocos introduz um tipo completamente novo para o ponteiro, enquanto ponteiros para funções aninhadas em GCC são ponteiros de função regulares e pode ser usado diretamente com o código existente.

Veja também

Referências

links externos