塊 (C語言擴展)

(blocks)是由LLVM提出的類似於lambda表達式的非標準C語言擴展,亦可以應用於Objective-CC++中。它的語法類似於這些函數中的閉包,即由大括號包括的語句塊。

蘋果設計塊的一個目的是使設計基於Grand Central Dispatch線程結構的程序更容易[1][2],但塊是獨立於這一構架的,它也可以在其它程序中以與普通語句塊十分相似的方式應用。蘋果已經在蘋果修改版的GCC編譯器以及Clang LLVM編譯器前端中實現了這一特性;同時,LLVM計劃,包括了支持塊特性的運行時庫

與函數定義類似,塊可以有參數,也可以在其內部聲明私有變量。與普通的C函數定義不同,塊可以使用其上文中定義的變量。一個塊定義會產生一個不透明的值,該值同時包括了塊內代碼的引用和定義時棧內局部變量的快照(而非調用時)。塊可以在定義後被調用,其行為與函數指針相同。塊可以如同函數指針一般被賦值到變量中,作為函數的參數傳遞,但若塊需要在其被定義的範圍之外被使用時,程序員(或API)需要將該塊用特別的運算符(Block_copy)標記。

在定義塊之後,塊內的代碼可以在任何時間被調用,語法與調用函數相同。

示例

一個簡單的計數器的例子:[3]

#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(void) {
	IntBlock mycounter = MakeCounter(5, 2);
	printf("First call: %d\n", mycounter());
	printf("Second call: %d\n", mycounter());
	printf("Third call: %d\n", mycounter());
	
	/* 由于是复制的块,因此需要释放 */
	Block_release(mycounter);
	
	return 0;
}
/* Output:
	First call: 5
	Second call: 7
	Third call: 9
*/

編譯

Linux:

clang -fblocks blocks-test.c -lBlocksRuntime

與GCC嵌套函數的關係

塊在外表上與GCC的C擴展語句塊內的嵌套函數相似[4]。然而,嵌套函數與塊不同,在退出當前語句塊後就不能被調用了。

C語言標準

塊特性已經被提交到C標準委員會,作為C1x標準的一系列提案[5][6]

參見

參考資料

外部連結