Skip to content

wikipedia Type qualifier

In the C, C++, and D programming languages, a type qualifier is a keyword that is applied to a type, resulting in a qualified type. For example, const int is a qualified type representing a constant integer, while int is the corresponding unqualified type, simply an integer. In D these are known as type constructors, by analogy with constructors in object-oriented programming.

Type qualifiers are a way of expressing additional information about a value through the type system, and ensuring correctness in the use of the data. Type qualifiers are not generally used outside the C/C++ family of languages: many languages have a notion of constants, but express this by the name binding being constant (a "variable that doesn't vary"), rather than through the type system; see alternatives, below.

NOTE: :在type前加上type qualifier就像创造了一个新的类型。

By language

C/C++

As of 2014 and C11, there are four type qualifiers in standard C: const (C89), volatile (C89), restrict (C99) and _Atomic (C11) – the latter has a private name to avoid clashing with user-defined names.[1] The first two of these, const and volatile, are also present in C++, and are the only type qualifiers in C++. Thus in C++ the term "cv-qualified type" (for const and volatile) is often used for "qualified type", while the terms "c-qualified type" and "v-qualified type" are used when only one of the qualifiers is relevant.

Of these, const is by far the best-known and most used, appearing in the C and C++ standard libraries and encountered in any significant use of these languages, which must satisfy const-correctness. The other qualifiers are used for low-level programming, and while widely used there, are rarely used by typical programmers. For a time however volatile was used by some C++ programmers for synchronization during threading, though this was discouraged and is now broken in most compilers.

Syntax

See also: C syntax § Type qualifiers

In C and C++, a type is given in a function declaration or variable declaration by giving one or more type specifiers, and optionally type qualifiers. For example, an integer variable can be declared as:

int x;

where int is the type specifier. An unsigned integer variable can be declared as:

unsigned int x;

where both unsigned and int are type specifiers. A constant unsigned integer variable can be declared as:

const unsigned int x;

where const is a type qualifier, which the qualified type of x is const unsigned int and the unqualified type is unsigned int.

Variable declarations further have an optional storage class specifier. Properly this is a separate topic, distinct from the type, though const on a variable declaration is also taken to have implications for the storage class, namely that it can be stored in read-only memory.

NOTE: : specifier和qualifiers存在差异

Volatile-correctness

See also: Const-correctness

The other qualifier in C and C++, volatile, indicates that an object may be changed by something external to the program at any time and so must be re-read from memory every time it is accessed.

The qualifier is most often found in code that manipulates hardware directly (such as in embedded systems and device drivers) and in multithreaded applications (though often used incorrectly in that context; see external links at volatile variable). It can be used in exactly the same manner as const in declarations of variables, pointers, references, and member functions, and in fact, volatile is sometimes used to implement a similar design-by-contract strategy which Andrei Alexandrescu calls volatile-correctness,[2] though this is far less common than const-correctness. The volatile qualifier also can be stripped by const_cast, and it can be combined with the const qualifier as in this sample:

// Set up a reference to a read-only hardware register that is
// mapped in a hard-coded memory location.
const volatile int & hardwareRegister  = *reinterpret_cast<int*>(0x8000);

int currentValue = hardwareRegister; // Read the memory location
int newValue = hardwareRegister;     // Read it again

hardwareRegister = 5; // Error, cannot write to a const location

Because hardwareRegister is volatile, there is no guarantee that it will hold the same value on two successive reads even though the programmer cannot modify it. The semantics here indicate that the register's value is read-only but not necessarily unchanging.

Alternatives

See also: const-correctness

Other languages take a different approach, considering constancy a property of an identifier (or name binding), not a type. Such languages thus have constant identifiers (corresponding to "variables" that do not vary) with single assignment, but do not have a notion of const-correctness: since constancy is not part of the type, there is no possibility of type mismatch. Examples include Ada 83 with constant objects and a constant keyword,[10][a]and Java with the final keyword.