Type qualifier

Last updated

a type qualifier is a analogy with constructors in object-oriented programming.

Contents

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.

D

In D the type constructors are const, immutable, shared, and inout. immutable is a stronger variant of const, indicating data that can never change its value, while const indicates data that cannot be changed through this reference: it is a constant view on possibly mutable data. shared is used for shared data in multi-threading (as volatile was briefly used for in C++). inout 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. const and immutable 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:

intx;

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

unsignedintx;

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

constunsignedintx;

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.

Volatile-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.constvolatileint&hardwareRegister=*reinterpret_cast<int*>(0x8000);intcurrentValue=hardwareRegister;// Read the memory locationintnewValue=hardwareRegister;// Read it againhardwareRegister=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.

History

The notion of a type qualifier was introduced, along with the example of readonly (later renamed const) by Bjarne Stroustrup in a Bell Labs internal Technical Memorandum of 1981, [3] and implemented in C with Classes, the predecessor to C++. [4] As to motivation, Stroustrup writes: [4]

"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."

const was then adopted in C as part of standardization, and appears in C89 (and subsequent versions) along with another type qualifier, volatile, which was invented by the ANSI C standard committee (X3J11). [5] volatile appeared by 1985; [6] 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. [7] A further qualifier, noalias, was suggested at the December 1987 meeting of the X3J11 committee, but was rejected; its goal was ultimately fulfilled by the restrict qualifier in C99. The motivation for noalias was complementary to volatile, 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; [8] he did oppose noalias however, and it was dropped from the draft.

Java does not have type qualifiers, and conspicuously omitted const: 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. [9] However, Java initially left open the possibility of implementing const, noticeable in that const is a reserved word, though it is not actually used as a keyword. Instead, Java has the object-oriented keyword final, 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 constant keyword, [10] [lower-alpha 1] and Java with the final keyword.

Notes

  1. The Ada standard calls this a "reserved word"; see that article for usage.

Related Research Articles

ANSI C, ISO C, and Standard C are successive standards for the C programming language published by the American National Standards Institute (ANSI) and ISO/IEC JTC 1/SC 22/WG 14 of the International Organization for Standardization (ISO) and the International Electrotechnical Commission (IEC). Historically, the names referred specifically to the original and best-supported version of the standard. Software developers writing in C are encouraged to conform to the standards, as doing so helps portability between compilers.

C is a general-purpose programming language. It was created in the 1970s by Dennis Ritchie and remains very widely used and influential. By design, C's features cleanly reflect the capabilities of the targeted CPUs. It has found lasting use in operating systems code, device drivers, and protocol stacks, but its use in application software has been decreasing. C is commonly used on computer architectures that range from the largest supercomputers to the smallest microcontrollers and embedded systems.

<span class="mw-page-title-main">C++</span> General-purpose programming language

C++ is a high-level, general-purpose programming language created by Danish computer scientist Bjarne Stroustrup. First released in 1985 as an extension of the C programming language, it has since expanded significantly over time; as of 1997, C++ has object-oriented, generic, and functional features, in addition to facilities for low-level memory manipulation for systems like microcomputers or to make operating systems like Linux or Windows. It is usually implemented as a compiled language, and many vendors provide C++ compilers, including the Free Software Foundation, LLVM, Microsoft, Intel, Embarcadero, Oracle, and IBM.

In object-oriented (OO) and functional programming, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created. In some cases, an object is considered immutable even if some internally used attributes change, but the object's state appears unchanging from an external point of view. For example, an object that uses memoization to cache the results of expensive computations could still be considered an immutable object.

<span class="mw-page-title-main">C syntax</span> Set of rules defining correctly structured programs

The syntax of the C programming language is the set of rules governing writing of software in C. It is designed to allow for programs that are extremely terse, have a close relationship with the resulting object code, and yet provide relatively high-level data abstraction. C was the first widely successful high-level language for portable operating-system development.

This article compares two programming languages: C# with Java. While the focus of this article is mainly the languages and their features, such a comparison will necessarily also consider some features of platforms and libraries. For a more detailed comparison of the platforms, see Comparison of the Java and .NET platforms.

In computer programming, volatile means that a value is prone to change over time, outside the control of some code. Volatility has implications within function calling conventions, and also impacts how variables are stored, accessed and cached.

<span class="mw-page-title-main">Java syntax</span> Set of rules defining correctly structured program

The syntax of Java is the set of rules defining how a Java program is written and interpreted.

In some programming languages, const is a type qualifier that indicates that the data is read-only. While this can be used to declare constants, const in the C family of languages differs from similar constructs in other languages in that it is part of the type, and thus has complicated behavior when combined with pointers, references, composite data types, and type-checking. In other languages, the data is not in a single memory location, but copied at compile time for each use. Languages which use it include C, C++, D, JavaScript, Julia, and Rust.

In the C programming language, data types constitute the semantics and characteristics of storage of data elements. They are expressed in the language syntax in form of declarations for memory locations or variables. Data types also determine the types of operations or methods of processing of data elements.

In the Java programming language, the final keyword is used in several contexts to define an entity that can only be assigned once.

typedef is a reserved keyword in the programming languages C, C++, and Objective-C. It is used to create an additional name (alias) for another data type, but does not create a new type, except in the obscure case of a qualified typedef of an array type where the typedef qualifiers are transferred to the array element type. As such, it is often used to simplify the syntax of declaring complex data structures consisting of struct and union types, although it is also commonly used to provide specific descriptive type names for integer data types of varying sizes.

A class in C++ is a user-defined type or data structure declared with any of the keywords class, struct or union that has data and functions as its members whose access is governed by the three access specifiers private, protected or public. By default access to members of a C++ class declared with the keyword class is private. The private members are not accessible outside the class; they can be accessed only through member functions of the class. The public members form an interface to the class and are accessible outside the class.

this, self, and Me are keywords used in some computer programming languages to refer to the object, class, or other entity which the currently running code is a part of. The entity referred to thus depends on the execution context. Different programming languages use these keywords in slightly different ways. In languages where a keyword like "this" is mandatory, the keyword is the only way to access data and methods stored in the current object. Where optional, these keywords can disambiguate variables and functions with the same name.

The C and C++ programming languages are closely related but have many significant differences. C++ began as a fork of an early, pre-standardized C, and was designed to be mostly source-and-link compatible with C compilers of the time. Due to this, development tools for the two languages are often integrated into a single product, with the programmer able to specify C or C++ as their source language.

C++11 is a version of the ISO/IEC 14882 standard for the C++ programming language. C++11 replaced the prior version of the C++ standard, called C++03, and was later replaced by C++14. The name follows the tradition of naming language versions by the publication year of the specification, though it was formerly named C++0x because it was expected to be published before 2010.

In computer programming, a constant is a value that is not altered by the program during normal execution. When associated with an identifier, a constant is said to be "named," although the terms "constant" and "named constant" are often used interchangeably. This is contrasted with a variable, which is an identifier with a value that can be changed during normal execution. To simplify, constants' values remains, while the values of variables varies, hence both their names.

In the C++ programming language, decltype is a keyword used to query the type of an expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.

"typename" is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type. In the original C++ compilers before the first ISO standard was completed, the typename keyword was not part of the C++ language and Bjarne Stroustrup used the class keyword for template arguments instead. While typename is now the preferred keyword, older source code may still use the class keyword instead.

References

  1. C11:The New C Standard, Thomas Plum
  2. "Generic<Programming>: volatile — Multithreaded Programmer's Best Friend Volatile-Correctness or How to Have Your Compiler Detect Race Conditions for You" by Andrei Alexandrescu in the C/C++ Users Journal C++ Experts Forum
  3. Bjarne Stroustrup, "Extensions of the C Language Type Concept.", Bell Labs internal Technical Memorandum, January 5, 1981.
  4. 1 2 Sibling Rivalry: C and C++, Bjarne Stroustrup, 2002, p. 5
  5. Dennis M. Ritchie, "The Development of the C Language Archived 2015-01-10 at archive.today ", 2003: "X3J11 also introduced a host of smaller additions and adjustments, for example, the type qualifiers const and volatile, and slightly different type promotion rules."
  6. It appears in the notes for the European UNIX System User Group (EUUC) meeting technical talk "The ANSI Draft Standard for the C Programming Language" by Mike Banahan, 1985 September 13, as printed in the Australian Unix systems User Group Newsletter (AUUGN), Vol 6, No 6, p. 73
  7. John Mashey (16 Aug 1991). "Re: RISC vs CISC? Call a spade a spade?". Newsgroup:  comp.arch. Usenet:   7037@spim.mips.COM.
  8. "Let me begin by saying that I'm not convinced that even the pre-December qualifiers ('const' and 'volatile') carry their weight; I suspect that what they add to the cost of learning and using the language is not repaid in greater expressiveness. 'Volatile', in particular, is a frill for esoteric applications, and much better expressed by other means. Its chief virtue is that nearly everyone can forget about it. 'Const' is simultaneously more useful and more obtrusive; you can't avoid learning about it, because of its presence in the library interface. Nevertheless, I don't argue for the extirpation of qualifiers, if only because it is too late."
  9. JDK-4211070: Java should support const parameters (like C++) for code maintainence[sic]
  10. 1815A, 3.2.1. Object Declarations:
    "The declared object is a constant if the reserved word constant appears in the object declaration; the declaration must then include an explicit initialization. The value of a constant cannot be modified after initialization. Formal parameters of mode in of subprograms and entries, and generic formal parameters of mode in, are also constants; a loop parameter is a constant within the corresponding loop; a subcomponent or slice of a constant is a constant."