Block (C-språktillägg)

Block är ett icke-standardiserat tillägg som lagts till av Apple Inc. till Clangs implementeringar av programmeringsspråken C , C++ och Objective-C som använder en lambda-uttrycksliknande syntax för att skapa stängningar inom dessa språk. Block stöds för program utvecklade för Mac OS X 10.6+ och iOS 4.0+, även om körtider från tredje part tillåter användning på Mac OS X 10.5 och iOS 2.2+ och icke-Apple-system.

Apple designade block med det uttryckliga målet att göra det enklare att skriva program för Grand Central Dispatch threading-arkitekturen, även om den är oberoende av den arkitekturen och kan användas på ungefär samma sätt som stängningar på andra språk. Apple har implementerat block både i sin egen gren av GNU Compiler Collection och i uppströms Clang LLVM -kompilatorns frontend. Språkkörningsbiblioteksstöd för block är också tillgängligt som en del av LLVM-projektet . Khronos-gruppen använder blocksyntax för att köa kärnor inifrån kärnor från och med version 2.0 av OpenCL .

Precis som funktionsdefinitioner kan block ta argument och deklarera sina egna variabler internt. Till skillnad från vanliga C-funktionsdefinitioner kan deras värde fånga tillstånd från deras omgivande kontext. En blockdefinition producerar ett ogenomskinligt värde som innehåller både en referens till koden i blocket och en ögonblicksbild av det aktuella tillståndet för lokala stackvariabler vid tidpunkten för dess definition. Blocket kan senare anropas på samma sätt som en funktionspekare. Blocket kan tilldelas variabler, skickas till funktioner och på annat sätt behandlas som en normal funktionspekare, även om applikationsprogrammeraren (eller API:et) måste markera blocket med en speciell operatör (Block_copy) om det ska användas utanför räckvidden i som det definierades.

Givet ett blockvärde kan koden i blocket exekveras vid vilken senare tidpunkt som helst genom att anropa den, med samma syntax som skulle användas för att anropa en funktion.

Exempel

iterator för heltalsområde :


 
 

  

     
	    
	
	   
		   
		  
		 
	
	


  
	    
	 
	 
	 
	
	
	
	
	 0
 /* blocks-test.c */  #include  <stdio.h>  #include  <Block.h>  /* Typ av block som inte tar något som returnerar en int */  typedef  int  (  ^  IntBlock  )();  IntBlock  MakeCounter  (  int  start  ,  int  inkrement  )  {  __block  int  i  =  start  ;  return  Block_copy  (  ^  (  void  )  {  int  ret  =  i  ;  i  +=  inkrement  ;  return  ret  ;  });  }  int  main  (  void  )  {  IntBlock  mycounter  =  MakeCounter  (  5  ,  2  );  printf  (  "Första samtal: %d  \n  "  ,  minräknare  ());  printf  (  "Andra anrop: %d  \n  "  ,  minräknare  ());  printf  (  "Tredje samtal: %d  \n  "  ,  minräknare  ());  /* eftersom det kopierades måste det också släppas */  Block_release  (  mycounter  );  återvända  ;  } 

Kompilera och kör




 $  clang -fblocks blocks-test.c  # Mac OS X  $  ./a.out  Första samtal: 5  Andra samtal: 7  Tredje samtal: 9 

Körtiden för blocken är inte en del av C-biblioteken som är länkade som standard på vissa system. Om så är fallet måste du explicit länka till detta bibliotek:

 $  clang -fblocks blocks-test.c -lBlocksRuntime  # Linux 

Körtiden är en del av clangs körtid, men är ibland inte installerad med clang-paketet. En fristående körtid extraherad från compiler-rt är tillgänglig.

Relation till GCC kapslade funktioner

Block har en ytlig likhet med GCC :s utvidgning av C för att stödja lexikalt omfångade kapslade funktioner . GCC:s kapslade funktioner, till skillnad från block, får dock inte anropas efter att det innehållande omfånget har avslutats, eftersom det skulle resultera i odefinierat beteende .

GCC-liknande kapslade funktioner använder för närvarande dynamiskt skapande av körbara thunks på de flesta arkitekturer när de tar adressen till den kapslade funktionen. På de flesta arkitekturer (inklusive X86) skapas dessa thunks på stacken, vilket kräver att stacken är körbar. Körbara stackar anses generellt vara ett potentiellt säkerhetshål. Block kräver inte användning av körbara thunks, så de delar inte denna svaghet. Å andra sidan introducerar block en helt ny typ för pekaren, medan pekare till kapslade funktioner i GCC är vanliga funktionspekare och kan användas direkt med befintlig kod.

Se även

externa länkar