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,   is a qualified type representing a constant integer, while   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 notation 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.

C/C++
and C11, there are four type qualifiers in standard C:  (C89),   (C89),   (C99) and   (C11) – the latter has a private name to avoid clashing with user-defined names. The first two of these,  and , 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,  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  was used by some C++ programmers for synchronization during threading, though this was discouraged and is now broken in most compilers.

D
In D the type constructors are,  ,  , and. is a stronger variant of, indicating data that can never change its value, while   indicates data that cannot be changed through this reference: it is a constant view on possibly mutable data. is used for shared data in multi-threading (as  was briefly used for in C++). is a wildcard used to allow functions that do not modify data (and thus are only concerned with the unqualified type of the data) to return the same qualified type as the input. and  can also be used as storage class specifiers.

Syntax
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: where  is the type specifier. An unsigned integer variable can be declared as: where both  and   are type specifiers. A constant unsigned integer variable can be declared as: where  is a type qualifier, which the qualified type of   is   and the unqualified type is.

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

Volatile-correctness
The other qualifier in C and C++,, 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  in declarations of variables, pointers, references, and member functions, and in fact,   is sometimes used to implement a similar design-by-contract strategy which Andrei Alexandrescu calls  -correctness, though this is far less common than  -correctness. The  qualifier also can be stripped by , and it can be combined with the   qualifier as in this sample:

Because  is , 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.

History
The notion of a type qualifier was introduced, along with the example of  (later renamed  ) by Bjarne Stroustrup in a Bell Labs internal Technical Memorandum of 1981, and implemented in C with Classes, the predecessor to C++. As to motivation, Stroustrup writes:
 * "It served two functions: as a way of defining a symbolic constant that obeys scope and type rules (that is, without using a macro) and as a way of deeming an object in memory immutable."

was then adopted in C as part of standardization, and appears in C89 (and subsequent versions) along with another type qualifier,, which was invented by the ANSI C standard committee (X3J11). appeared by 1985; and an early use was in compiling the UNIX kernel for MIPS, to allow optimized compiling by preventing usual optimizations from being applied to volatile variables. A further qualifier,, was suggested at the December 1987 meeting of the X3J11 committee, but was rejected; its goal was ultimately fulfilled by the   qualifier in C99. The motivation for  was complementary to , namely that it indicated that even normally unsafe optimizations could be performed. Ritchie was not very supportive of type qualifiers, arguing that they did not "carry their weight", but ultimately did not argue for their removal from the standard; he did oppose  however, and it was dropped from the draft.

Java does not have type qualifiers, and conspicuously omitted : a 1999 proposal to add it was rejected, notably because adding it after the fact and then changing the standard library to use it consistently would have broken compatibility. However, Java initially left open the possibility of implementing, noticeable in that   is a reserved word, though it is not actually used as a keyword. Instead, Java has the object-oriented keyword, which is used to qualify attributes (and thence also for local variables) as constant, but not to qualify types.

Alternatives
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  keyword,  and Java with the   keyword.