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.
Conteúdo
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
- Encerramento (informática)
- escopo léxico
- Lambda (programação)
- pilha Spaghetti
- Thunk (programação funcional)
- XNU
- C ++ 11 (inclui "expressões lambda")
Referências
links externos
- "Clang idioma Extensões: Blocos" . Projeto LLVM . Retirado 2013/01/20 .
- " " Compiler-rt "Runtime Library" . Projeto LLVM . Retirado 2013/01/20 .