塊 (C語言擴展)
塊(blocks)是由LLVM提出的類似於lambda表達式的非標準C語言擴展,亦可以應用於Objective-C與C++中。它的語法類似於這些函數中的閉包,即由大括號包括的語句塊。
蘋果設計塊的一個目的是使設計基於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嵌套函數的關係
C語言標準
參見
參考資料
- ^ Apple Technical Brief on Grand Central Dispatch (頁面存檔備份,存於網際網路檔案館), retrieved on June 9, 2009.
- ^ Mac OS X 10.6 Snow Leopard: the Ars Technica review: Blocks. [2010-09-15]. (原始內容存檔於2010-09-04).
- ^ : Bengtsson, J. Programming with C Blocks on Apple Devices. [2010-09-15]. (原始內容存檔於2017-11-15).
- ^ Nested Functions: Using the GNU Compiler Collection (GCC). [2010-09-15]. (原始內容存檔於2010-08-21).
- ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1370.pdf (頁面存檔備份,存於網際網路檔案館) BLOCKS PROPOSAL, N1451
- ^ http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1451.pdf (頁面存檔備份,存於網際網路檔案館) APPLE』S EXTENSIONS TO C, N1451
外部連結
- Clang Language Extensions: Blocks. LLVM Project. [2010-06-09]. (原始內容存檔於2010-07-16).
- "compiler-rt" Blocks Runtime Library | Blocks Runtime. LLVM Project. [2011-03-25]. (原始內容存檔於2009-07-06).