Kvalifikátory typu
Kvalifikátory typu poskytují identifikátoru jednu ze dvou vlastností. Kvalifikátor const
typu deklaruje objekt, který není možné upravit. volatile
Kvalifikátor typu deklaruje položku, jejíž hodnota může být oprávněně změněna něčím, co přesahuje kontrolu nad programem, ve kterém se zobrazuje, například souběžným spuštěním vlákna.
Kvalifikátory typu , const
, restrict
a volatile
, mohou být zobrazeny pouze jednou v deklaraci. Kvalifikátory typu se mohou objevit s libovolným specifikátorem typu; Nemohou se však zobrazit za první čárkou v deklaraci více položek. Například následující deklarace jsou právní:
typedef volatile int VI;
const int ci;
Tyto deklarace nejsou legální:
typedef int *i, volatile *vi;
float f, const cf;
Kvalifikátory typu jsou relevantní pouze při přístupu k identifikátorům jako l-hodnot ve výrazech. Informace o l-hodnotáchach
Syntaxe
type-qualifier
:
const
restrict
volatile
const
a volatile
Toto jsou právní const
prohlášení a volatile
prohlášení:
int const *p_ci; // Pointer to constant int
int const (*p_ci); // Pointer to constant int
int *const cp_i; // Constant pointer to int
int (*const cp_i); // Constant pointer to int
int volatile vint; // Volatile integer
Pokud specifikace typu pole zahrnuje kvalifikátory typu, je prvek kvalifikovaný, nikoli typ pole. Pokud specifikace typu funkce zahrnuje kvalifikátory, chování není definováno. volatile
a const
nemá vliv na rozsah hodnot nebo aritmetických vlastností objektu.
Klíčové
const
slovo lze použít k úpravě jakéhokoli základního nebo agregovaného typu nebo ukazatele na objekt libovolného typu nebo .typedef
Pokud je položka deklarována pouze s kvalifikátoremconst
typu, jeho typ se použije jako const int. Proměnnouconst
je možné inicializovat nebo ji umístit do oblasti úložiště jen pro čtení. Klíčovéconst
slovo je užitečné pro deklarování ukazatelů,const
protože to vyžaduje, aby funkce nezměnila ukazatel žádným způsobem.Kompilátor předpokládá, že v libovolném okamžiku programu
volatile
může být proměnná přístupná neznámým procesem, který používá nebo upravuje jeho hodnotu. Bez ohledu na optimalizace zadané na příkazovém řádku musí být kód pro každé přiřazení nebo odkaz na proměnnouvolatile
generován, i když se zdá, že nemá žádný vliv.
Pokud volatile
se používá samostatně, int
předpokládá se. Specifikátor volatile
typu lze použít k zajištění spolehlivého přístupu ke speciálním umístěním paměti. Používá se volatile
s datovými objekty, ke kterým může přistupovat nebo měnit obslužné rutiny signálu, souběžné spouštění programů nebo speciální hardware, jako jsou registrace ovládacích prvků v/V mapovaných paměti. Proměnnou můžete deklarovat jako její volatile
životnost, nebo můžete přetypovat jeden odkaz na volatile
hodnotu .
- Položka může být obě
const
avolatile
v takovém případě nelze položku legitimním způsobem upravit vlastním programem, ale může být upravena nějakým asynchronním procesem.
restrict
Kvalifikátor restrict
typu zavedený v jazyce C99 a dostupný v /std:c11
režimu nebo /std:c17
v režimu lze použít pro deklarace ukazatelů. Kvalifikuje ukazatel, nikoli to, na co ukazuje.
restrict
je optimalizační tip kompilátoru, že žádný jiný ukazatel v aktuálním oboru odkazuje na stejné umístění paměti. To znamená, že pro přístup k objektu během doby života ukazatele se používá pouze ukazatel nebo hodnota odvozená z něj (například ukazatel + 1). To kompilátoru pomáhá vytvářet optimalizovanější kód. C++ má ekvivalentní mechanismus, __restrict
Mějte na paměti, že restrict
jde o kontrakt mezi vámi a kompilátorem. Pokud vytvoříte alias ukazatele označeného značkou restrict
, výsledek je nedefinovaný.
Tady je příklad, který používá restrict
:
void test(int* restrict first, int* restrict second, int* val)
{
*first += *val;
*second += *val;
}
int main()
{
int i = 1, j = 2, k = 3;
test(&i, &j, &k);
return 0;
}
// Marking union members restrict tells the compiler that
// only z.x or z.y will be accessed in any scope, which allows
// the compiler to optimize access to the members.
union z
{
int* restrict x;
double* restrict y;
};