Prec.     Page 41     Suiv.

3.5 Program and linkage 

[basic.link]

  1. A program consists of one or more translation units (clause 2) linked together. A translation unit consists of a sequence of declarations.
    translation­unit:
         declaration­seqopt
  2. A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:

  3. A name having namespace scope (3.3.5) has internal linkage if it is the name of

  4. A name having namespace scope has external linkage if it is the name of

  5. In addition, a member function, static data member, class or enumeration of class scope has external linkage if the name of the class has external linkage.

  6. The name of a function declared in block scope, and the name of an object declared by a block scope extern declaration, have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill­formed. Otherwise, if no matching entity is found,the block scope entity receives external linkage.

    Prec.     Page 42     Suiv.


    [Example:

        static void f();
        static int i = 0;        // 1
        void g() {
            extern void f();     // internal linkage
            int i;               // 2: i has no linkage
            {
                extern void f(); // internal linkage
                extern int i;    // 3: external linkage
            }
        }

    There are three objects named i in this program. The object with internal linkage introduced by the declaration in global scope (line // 1), the object with automatic storage duration and no linkage introduced by the declaration on line // 2, and the object with static storage duration and external linkage introduced by the declaration on line // 3. ]

  7. When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope. [Example:

        namespace X {
            void p()
            {
                q();               //
    error: q not yet declared
                extern void q();   // q
    is a member of namespace X
            }

            void middle()
            {
                q();               //
    error: q not yet declared
            }

            void q() { /* ... */ } // definition of X::q
        }

        void q() { /* ... */ }     // some other, unrelated q

    --end example]

  8. Names not covered by these rules have no linkage. Moreover, except as noted, a name declared in a local scope (3.3.2) has no linkage. A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.2)) shall not be used to declare an entity with linkage. If a declaration uses a typedef name, it is the linkage of the type name to which the typedef refers that is considered. [Example:

        void f()
        {
                struct A { int x; }; //
    no linkage
                extern A a;          //
    ill­formed
                typedef A B;
                extern B b;          //
    ill­formed
        }

    --end example] This implies that names with no linkage cannot be used as template arguments (14.3).

  9. Two names that are the same (clause 3) and that are declared in different scopes shall denote the same object, reference, function, type, enumerator, template or namespace if

  10. After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given object or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.
  11. [Note: linkage to non­C++ declarations can be achieved using a linkage­specification (7.5). ]

3.6 Start and termination

[basic. start]

3.6.1 Main function

[basic. start. main]

  1. A program shall contain a global function called main, which is the designated start of the program. It is implementation­defined whether a program in a freestanding environment is required to define a main function. [Note: in a freestanding environment, start­up and termination is implementation­defined; start­up contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration. ]
  2. An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation­defined. All implementations shall allow both of the following definitions of main:

        int main() { /* ... */ }

    and

        int main (int argc, char* argv[]) { /* ... */ }

    In the latter form argc shall be the number of arguments passed to the program from the environment in which the program is run. If argc is nonzero these arguments shall be supplied in argv [0] through argv [argc­1] as pointers to the initial characters of null­terminated multibyte strings (NTMBSs) (17.3.2.1.3.2) and argv [0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "". The value of argc shall be nonnegative. The value of argv [argc] shall be 0. [Note: it is recommended that any further (optional) parameters be added after argv. ]

  3. The function main shall not be used (3.2) within a program. The linkage (3.5) of main is implementation­defined. A program that declares main to be inline or static is ill­formed. The name main is not otherwise reserved. [Example: member functions, classes, and enumerations can be called main, as can entities in other namespaces. ]
  4. Calling the function

        void exit (int);

    declared in <cstdlib> (18.3) terminates the program without leaving the current block and hence without destroying any objects with automatic storage duration (12.4). If exit is called to end a program during the destruction of an object with static storage duration, the program has undefined behavior.

  5. A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing

        return 0;


Prec.     Page 44     Suiv.

3.6.2 Initialization of non­local objects

[basic. start. init]

  1. The storage for objects with static storage duration (3.7.1) shall be zero­initialized (8.5) before any other initialization takes place. Zero­initialization and initialization with a constant expression are collectively called static initialization; all other initialization is dynamic initialization. Objects of POD types (3.9) with static storage duration initialized with constant expressions (5.19) shall be initialized before any dynamic initialization takes place. Objects with static storage duration defined in namespace scope in the same translation unit and dynamically initialized shall be initialized in the order in which their definition appears in the translation unit. [Note: 8.5.1 describes the order in which aggregate members are initialized. The initialization of local static objects is described in 6.7. ]
  2. An implementation is permitted to perform the initialization of an object of namespace scope with static storage duration as a static initialization even if such initialization is not required to be done statically, provided that

    [Note: as a consequence, if the initialization of an object obj1 refers to an object obj2 of namespace scope with static storage duration potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 merely zero­initialized. For example,

       inline double fd() { return 1.0; }
       extern double d1;
       double d2 = d1;   //
    unspecified:
                         //
    may be statically initialized to 0.0 or
                         //
    dynamically initialized to 1.0
       double d1 = fd(); //
    may be initialized statically to 1.0

    --end note]

    It is implementation­defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or object defined in the same translation unit as the object to be initialized. 31) [Example:

        // - File 1 -
        #include "a.h"
        #include "b.h"
        B b;
        A::A(){
           b.Use();
        }

        // - File 2 -
        #include "a.h"
        A a;


    Prec.      Page 45     Suiv.

       // - File 3 -
        #include "a.h"
        #include "b.h"
        extern A a;
        extern B b;

        int main() {
           a.Use();
           b.Use();
        }

  3. It is implementation­defined whether either a or b is initialized before main is entered or whether the initializations are delayed until a is first used in main. In particular, if a is initialized before main is entered, it is not guaranteed that b will be initialized before it is used by the initialization of a, that is, before A::A is called. If, however, a is initialized at some point after the first statement of main, b will be initialized prior to its use in A::A. ]

  4. If construction or destruction of a non­local static object ends in throwing an uncaught exception, the result is to call terminate (18.6.3.3).

3.6.3 Termination

[basic. start. term]

  1. Destructors (12.4) for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit (18.3). These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization. If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the sub­objects is destroyed.
  2. If a function contains a local object of static storage duration that has been destroyed and the function is called during the destruction of an object with static storage duration, the program has undefined behavior if the flow of control passes through the definition of the previously destroyed local object.
  3. If a function is registered with atexit (see <cstdlib>, 18.3) then following the call to exit, any objects with static storage duration initialized prior to the registration of that function shall not be destroyed until the registered function is called from the termination process and has completed. For an object with static storage duration constructed after a function is registered with atexit, then following the call to exit, the registered function is not called until the execution of the object's destructor has completed. If atexit is called during the construction of an object, the complete object to which it belongs shall be destroyed before the registered function is called.
  4. Calling the function

        void abort();

    declared in <cstdlib> terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit().

3.7 Storage duration 

[basic.stc]

  1. Storage duration is the property of an object that defines the minimum potential lifetime of the storage containing the object. The storage duration is determined by the construct used to create the object and is one of the following:

    -- static storage duration
    -- automatic storage duration
    -- dynamic storage duration


    Prec.      Page 46     Suiv.

  2. Static and automatic storage durations are associated with objects introduced by declarations (3.1) and implicitly created by the implementation (12.2). The dynamic storage duration is associated with objects created with operator new (5.3.4).
  3. The storage class specifiers static and auto are related to storage duration as described below.
  4. The storage duration categories apply to references as well. The lifetime of a reference is its storage duration.

3.7.1 Static storage duration

[basic.stc.static]

  1. All objects which neither have dynamic storage duration nor are local have static storage duration. The storage for these objects shall last for the duration of the program (3.6.2, 3.6.3).
  2. If an object of static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8.
  3. The keyword static can be used to declare a local variable with static storage duration. [Note: 6.7 describes the initialization of local static variables; 3.6.3 describes the destruction of local static variables. ]
  4. The keyword static applied to a class data member in a class definition gives the data member static storage duration.

3.7.2 Automatic storage duration

[basic.stc.auto]

  1. Local objects explicitly declared auto or register or not explicitly declared static or extern have automatic storage duration. The storage for these objects lasts until the block in which they are created exits.
  2. [Note: these objects are initialized and destroyed as described in 6.7. ]
  3. If a named automatic object has initialization or a destructor with side effects, it shall not be destroyed before the end of its block, nor shall it be eliminated as an optimization even if it appears to be unused, except that a class object or its copy may be eliminated as specified in 12.8.

3.7.3 Dynamic storage duration

[basic.stc.dynamic]

  1. Objects can be created dynamically during program execution (1.9), using new­expressions (5.3.4), and destroyed using delete­expressions (5.3.5). A C++ implementation provides access to, and management of, dynamic storage via the global allocation functions operator new and operator new[] and the global deallocation functions operator delete and operator delete[].
  2. The library provides default definitions for the global allocation and deallocation functions. Some global allocation and deallocation functions are replaceable (18.4.1). A C++ program shall provide at most one definition of a replaceable allocation or deallocation function. Any such function definition replaces the default version provided in the library (17.4.3.4). The following allocation and deallocation functions (18.4) are implicitly declared in global scope in each translation unit of a program

        void* operator new (std::size_t) throw (std::bad_alloc);
        void* operator new[] (std::size_t) throw (std::bad_alloc);
        void operator delete (void*) throw();
        void operator delete[] (void*) throw();

    These implicit declarations introduce only the function names operator new, operator new[], operator delete, operator delete[]. [Note: the implicit declarations do not introduce the names std, std::bad_alloc, and std::size_t, or any other names that the library uses to declare these names. Thus, a new­expression, delete­expression or function call that refers to one of these functions without including the header <new> is well­formed. However, referring to std, std::bad_alloc, and std::size_t is ill­formed unless the name has been declared by including the appropriate header. ]

    Allocation and/ or deallocation functions can also be declared and defined for any class (12.5).

    3 Any allocation and/ or deallocation functions defined in a C++ program shall conform to the semantics specified in 3.7.3.1 and 3.7.3.2.


Prec.      Page 47     Suiv.

3.7.3.1 Allocation functions

[basic.stc.dynamic.allocation]

  1. An allocation function shall be a class member function or a global function; a program is ill­formed if an allocation function is declared in a namespace scope other than global scope or declared static in global scope. The return type shall be void*. The first parameter shall have type size_t (18.1). The first parameter shall not have an associated default argument (8.3.6). The value of the first parameter shall be interpreted as the requested size of the allocation. An allocation function can be a function template. Such a template shall declare its return type and first parameter as specified above (that is, template parameter types shall not be used in the return type and first parameter type). Template allocation functions shall have two or more parameters.
  2. The allocation function attempts to allocate the requested amount of storage. If it is successful, it shall return the address of the start of a block of storage whose length in bytes shall be at least as large as the requested size. There are no constraints on the contents of the allocated storage on return from the alloca­tion function. The order, contiguity, and initial value of storage allocated by successive calls to an allocation function is unspecified. The pointer returned shall be suitably aligned so that it can be converted to a pointer of any complete object type and then used to access the object or array in the storage allocated (until the storage is explicitly deallocated by a call to a corresponding deallocation function). If the size of the space requested is zero, the value returned shall not be a null pointer value (4.10). The results of dereferencing a pointer returned as a request for zero size are undefined. 32)
  3. An allocation function that fails to allocate storage can invoke the currently installed new_handler (18.4.2.2), if any. [Note: A program­supplied allocation function can obtain the address of the currently installed new_handler using the set_new_handler function (18.4.2.3)]. If an allocation function declared with an empty exception­specification (15.4), throw(), fails to allocate storage, it shall return a null pointer. Any other allocation function that fails to allocate storage shall only indicate failure by throwing an exception of class std::bad_alloc (18.4.2.1) or a class derived from std::bad_alloc.
  4. A global allocation function is only called as the result of a new expression (5.3.4), or called directly using the function call syntax (5.2.2), or called indirectly through calls to the functions in the C++ standard library. [Note: in particular, a global allocation function is not called to allocate storage for objects with static storage duration (3.7.1), for objects of type type_info (5.2.8), for the copy of an object thrown by a throw expression (15.1). ]

 

3.7.3.2 Deallocation functions

[basic.stc.dynamic.deallocation]

  1. Deallocation functions shall be class member functions or global functions; a program is ill­formed if deallocation functions are declared in a namespace scope other than global scope or declared static in global scope.
  2. Each deallocation function shall return void and its first parameter shall be void*. A deallocation func­tion can have more than one parameter. If a class T has a member deallocation function named operator delete with exactly one parameter, then that function is a usual (non­placement) deallocation function. If class T does not declare such an operator delete but does declare a member deallocation function named operator delete with exactly two parameters, the second of which has type std::size_t (18.1), then this function is a usual deallocation function. Similarly, if a class T has a member deallocation function named operator delete[] with exactly one parameter, then that function is a usual (non­placement) deallocation function. If class T does not declare such an operator delete[] but does declare a member deallocation function named operator delete[] with exactly two parameters, the second of which has type std::size_t, then this function is a usual deallocation function. A deallocation function can be an instance of a function template. Neither the first parameter nor the return type shall depend on a template parameter. [Note: that is, a deallocation function template shall have a first parameter of type void* and a return type of void (as specified above). ] A deallocation function template shallhave two or more function parameters. A template instance is never a usual deallocation function, regard­less of its signature.

  3. Prec.      Page 48     Suiv.

  4. The value of the first argument supplied to one of the deallocation functions provided in the standard library may be a null pointer value; if so, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete (void*) in the standard library shall be one of the values returned by a previous invocation of either operator new (size_t) or operator new (size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete[] (void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[] (size_t) or operator new[] (size_t, const std::nothrow_t&) in the standard library.
  5. If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value (4.10), the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage. The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined. 33)

3.7.4 Duration of sub­objects

[basic.stc.inherit]

  1. The storage duration of member subobjects, base class subobjects and array elements is that of their complete object (1.8).

3.8 Object Lifetime

[basic.life]

  1. The lifetime of an object is a runtime property of the object. The lifetime of an object of type T begins when:

    - storage with the proper alignment and size for type T is obtained, and
    - if T is a class type with a non­trivial constructor (12.1), the constructor call has completed.

    The lifetime of an object of type T ends when:

    - if T is a class type with a non­trivial destructor (12.4), the destructor call starts, or
    - the storage which the object occupies is reused or released.

  2. [Note: the lifetime of an array object or of an object of type (3.9) starts as soon as storage with proper size and alignment is obtained, and its lifetime ends when the storage which the array or object occupies is reused or released. 12.6.2 describes the lifetime of base and member subobjects. ]
  3. The properties ascribed to objects throughout this International Standard apply for a given object only during its lifetime. [Note: in particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the object, as described below, in 12.6.2 and in 12.7. Also, the behavior of an object under construction and destruction might not be the same as the behavior of an objectwhose lifetime has started and not ended. 12.6.2 and 12.7 describe the behavior of objects during the con­struction and destruction phases. ]
  4. A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non­trivial destructor. For an object of a class type with a non­trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete­expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
     

    Prec.      Page 49     Suiv.
  5. Before the lifetime of an object has started but after the storage which the object will occupy has been allocated 34) or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. Such a pointer refers to allocated storage (3.7.3.2), and using the pointer as if the pointer were of type void*, is well­defined. Such a pointer may be dereferenced but the resulting lvalue may only be used in limited ways, as described below. If the object will be or was of a class type with a non­trivial destructor, and the pointer is used as the operand of a delete­expression, the program has undefined behavior. If the object will be or was of a nonPOD class type, the program has undefined behavior if:

    -- the pointer is used to access a non­static data member or call a non­static member function of the object, or
    -- the pointer is implicitly converted (4.10) to a pointer to a base class type, or
    -- the pointer is used as the operand of a static_cast (5.2.9) (except when the conversion is to void*, or to void* and subsequently to char*, or unsigned char*).

    -- the pointer is used as the operand of a dynamic_cast (5.2.7). [Example:

        struct B {
            virtual void f();
            void mutate();
            virtual ~B();
        };

        struct D1 : B { void f(); };
        struct D2 : B { void f(); };

        void B::mutate() {
            new (this) D2;     // reuses storage - ends the lifetime of *this
            f();               // undefined behavior
            ... = this;        // OK, this points to valid memory
        }

        void g() {
            void* p = malloc (sizeof( D1) + sizeof (D2));
            B* pb = new (p) D1;
            pb­> mutate();
            &pb;             // OK: pb points to valid memory
            void* q = pb;    // OK: pb points to valid memory
            pb­> f();        // undefined behavior, lifetime of *pb has ended
        }

    -- end example]

  6. Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any lvalue which refers to the original object may be used but only in limited ways. Such an lvalue refers to allocated storage (3.7.3.2), and using the properties of the lvalue which do not depend on its value is well­defined. If an lvalue­to­rvalue conversion (4.1) is applied to such an lvalue, the program has undefined behavior; if the original object will be or was of a non­POD class type, the program has undefined behavior if:
     

    Prec.     Page 50     Suiv.
    - the lvalue is used to access a non­static data member or call a non­static member function of the object, or
    - the lvalue is implicitly converted (4.10) to a reference to a base class type, or
    - the lvalue is used as the operand of a static_cast (5.2.9) (except when the conversion is ultimately to char& or unsigned char&), or
    - the lvalue is used as the operand of a dynamic_cast (5.2.7) or as the operand of typeid.
  7. If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:

    - the storage for the new object exactly overlays the storage location which the original object occupied, and
    - the new object is of the same type as the original object (ignoring the top­level cv­qualifiers), and
    - the original object was a most derived object (1.8) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects). [Example:

        struct C {
            int i;
            void f();
            const C& operator=( const C& );
        };

        const C& C::operator= (const C& other)
        {
            if (this != &other ) {
                this­>~ C();          // lifetime of *this ends
                new (this) C (other); // new object of type C created
                f();                  // well­defined
            }
            return *this;
        }

        C c1;
        C c2;
        c1 = c2;                     // well­defined
        c1. f();                     // well­defined; c1 refers to a new object of type C

    --end example]

  8. If a program ends the lifetime of an object of type T with static (3.7.1) or automatic (3.7.2) storage duration and if T has a non­trivial destructor, 35) the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the pro­gram is undefined. This is true even if the block is exited with an exception. [Example:

        class T { };
        struct B {
            ~B();
        };

        void h() {
            B b;
            new (& b) T;
        } // undefined behavior at block exit

    --end example]


    Prec.      Page 51     Suiv.
  9. Creating a new object at the storage location that a const object with static or automatic storage duration occupies or, at the storage location that such a const object used to occupy before its lifetime ended results in undefined behavior. [Example:

        struct B {
            B();
            ~B();
        };

        const B b;
        void h() {
            b.~ B();
            new (& b) const B; // undefined behavior
        }

    --end example]

3.9 Types

[basic.types]

  1. [Note: 3.9 and the subclauses thereof impose requirements on implementations regarding the representation of types. There are two kinds of types: fundamental types and compound types. Types describe objects (1.8), references (8.3.2), or functions (8.3.5). ]
  2. For any complete POD object type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char. 36) If the con­tent of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value. [Example:

        #define N sizeof (T)
        char buf [N];
        T obj;                 // obj initialized to its original value
        memcpy (buf, &obj, N); // between these two calls to memcpy,
                               // obj might be modified
        memcpy(& obj, buf, N); // at this point, each subobject of obj of scalar type
                               // holds its original value

    --end example]

  3. For any POD type T, if two pointers to T point to distinct T objects obj1 and obj2, if the value of obj1 is copied into obj2, using the memcpy library function, obj2 shall subsequently hold the same value as obj1. [Example:

        T* t1p;
        T* t2p;
                                        // provided that t2p points to an initialized object ...
        memcpy (t1p, t2p, sizeof (T));  // at this point, every subobject of POD type in *t1p contains
                                        // the same value as the corresponding subobject in *t2p

    --end example]

  4. The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof (T). The value representation of an object is the set of bits that hold the value of type T. For POD types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation­defined set of values. 37)
  5. Object types have alignment requirements (3.9.1, 3.9.2). The alignment of a complete object type is an implementation­defined integer value representing a number of bytes; an object is allocated at an address that meets the alignment requirements of its object type.

    Prec.      Page 52     Suiv.
  6. A class that has been declared but not defined, or an array of unknown size or of incomplete element type,
    is an incompletely­defined object type. 38) Incompletely­defined object types and the void types are incomplete
    types (3.9.1). Objects shall not be defined to have an incomplete type.
  7. A class type (such as "class X") might be incomplete at one point in a translation unit and complete later on; the type "class X" is the same type at both points. The declared type of an array object might be an array of incomplete class type and therefore incomplete; if the class type is completed later on in the trans­lation unit, the array type becomes complete; the array type at those two points is the same type. The declared type of an array object might be an array of unknown size and therefore be incomplete at one point in a translation unit and complete later on; the array types at those two points (" array of unknown bound of T" and "array of N T") are different types. The type of a pointer to array of unknown size, or of a type defined by a typedef declaration to be an array of unknown size, cannot be completed. [Example:

        class X;             // X is an incomplete type
        extern X* xp;        // xp is a pointer to an incomplete type
        extern int arr[];    // the type of arr is incomplete
        typedef int UNKA[];  // UNKA is an incomplete type
        UNKA* arrp;          // arrp is a pointer to an incomplete type
        UNKA** arrpp;

        void foo()
        {
            xp++;             // ill­formed: X is incomplete
            arrp++;           // ill­formed: incomplete type
            arrpp++;          // OK: sizeof UNKA* is known
        }

        struct X { int i; }; // now X is a complete type
        int arr [10];        // now the type of arr is complete

        X x;
        void bar()
        {
            xp = &x;         // OK; type is '' pointer to X''
            arrp = &arr;     // ill­formed: different types
            xp++;            // OK: X is complete
            arrp++;          // ill­formed: UNKA can't be completed
        }

    --end example]

  8. [Note: the rules for declarations and expressions describe in which contexts incomplete types are prohibited. ]
  9. An object type is a (possibly cv­qualified) type that is not a function type, not a reference type, and not a void type.
  10. Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cv­qualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD­struct types, POD­union types (clause 9), arrays of such types and cv­qualified versions of these types (3.9.3) are collectively called POD types.
  11. If two types T1 and T2 are the same type, then T1 and T2 are layout­compatible types. [Note: Layout­compatible enumerations are described in 7.2. Layout­compatible POD­structs and POD­unions are described in 9.2. ]

Prec.      Page 53     Suiv.

3.9.1 Fundamental types

[basic.fundamental]

  1. Objects declared as characters (char) shall be large enough to store any member of the implementation's basic character set. If a character from this set is stored in a character object, the integral value of that character object is equal to the value of the single character literal form of that character. It is implementation­defined whether a char object can hold negative values. Characters can be explicitly declared unsigned or signed. Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an unsigned char occupy the same amount of storage and have the same align­ment requirements (3.9); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. In any particular implementation, a plain char object can take on either the same values as a signed char or an unsigned char; which one is implementation­defined.
  2. There are four signed integer types: "signed char", "short int", "int", and "long int." In this list, each type provides at least as much storage as those preceding it in the list. Plain ints have the natural size suggested by the architecture of the execution environment 39) ; the other signed integer types are provided to meet special needs.
  3. For each of the signed integer types, there exists a corresponding (but different) unsigned integer type: "unsigned char", "unsigned short int", "unsigned int", and "unsigned long int," each of which occupies the same amount of storage and has the same alignment requirements (3.9) as the corresponding signed integer type 40) ; that is, each signed integer type has the same object representation as its corresponding unsigned integer type. The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the value representation of each corresponding signed/ unsigned type shall be the same.
  4. Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2 n where n is the number of bits in the value representation of that particular size of integer. 41)
  5. Type wchar_ t is a distinct type whose values can represent distinct codes for all members of the largest extended character set specified among the supported locales (22.1.1). Type wchar_t shall have the same size, signedness, and alignment requirements (3.9) as one of the other integral types, called its underlying type.
  6. Values of type bool are either true or false. 42) [Note: there are no signed, unsigned, short, or long bool types or values]. As described below, bool values behave as integral types. Values of type bool participate in integral promotions (4.5).
  7. Types bool, char, wchar_t, and the signed and unsigned integer types are collectively called integral types. 43) A synonym for integral type is integer type. The representations of integral types shall define values by use of a pure binary numeration system. 44) [Example: this International Standard permits 2's complement, 1's complement and signed magnitude representations for integral types. ]
  8. There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value repre­sentation of floating­point types is implementation­defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template numeric_limits (18.2) shall specify the maximum and minimum values of each arithmetic type for an implementation.
     

    Prec.      Page 54     Suiv.
  9. The void type has an empty set of values. The void type is an incomplete type that cannot be completed. It is used as the return type for functions that do not return a value. Any expression can be explicitly converted to type cv void (5.4). An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression (5.18), as a second or third operand of ?: (5.16), as the operand of typeid, or as the expression in a return statement (6.6.3) for a function with the return type void.
  10. [Note: even if the implementation defines two or more basic types to have the same value representation, they are nevertheless different types. ]
     

    3.9.2 Compound types

    [basic.compound]

    1. Compound types can be constructed in the following ways:

      -- arrays of objects of a given type, 8.3.4;
      -- functions, which have parameters of given types and return void or references or objects of a given type, 8.3.5;

      -- pointers to void or objects or functions (including static members of classes) of a given type, 8.3.1;
      -- references to objects or functions of a given type, 8.3.2;
      -- classes containing a sequence of objects of various types (clause 9), a set of types, enumerations and functions for manipulating these objects (9.3), and a set of restrictions on the access to these entities (clause 11);

      -- unions, which are classes capable of containing objects of different types at different times, 9.5;
      -- enumerations, which comprise a set of named constant values. Each distinct enumeration constitutes a different enumerated type, 7.2;

      -- pointers to non­static 45) class members, which identify members of a given type within objects of a given class, 8.3.3.

    2. These methods of constructing types can be applied recursively; restrictions are mentioned in 8.3.1, 8.3.4, 8.3.5, and 8.3.2.

    3. A pointer to objects of type T is referred to as a "pointer to T." [Example: a pointer to an object of type int is referred to as "pointer to int" and a pointer to an object of class X is called a "pointer to X." ] Except for pointers to static members, text referring to "pointers" does not apply to pointers to members. Pointers to incomplete types are allowed although there are restrictions on what can be done with them (3.9). The value representation of pointer types is implementation­defined. Pointers to cv­qualified and cv­unqualified versions (3.9.3) of layout­compatible types shall have the same value representation and alignment requirements (3.9).

    4. Objects of cv­qualified (3.9.3) or cv­unqualified type void* (pointer to void), can be used to point to objects of unknown type. A void* shall be able to hold any object pointer. A cv­qualified or cv­unqualified (3.9.3) void* shall have the same representation and alignment requirements as a cv­qualified or cv­unqualified char*.
       

      Prec.     Page 55     Suiv.

      3.9.3 CV­qualifiers

      [basic.type.qualifier]

      1. A type mentioned in 3.9.1 and 3.9.2 is a cv­unqualified type. Each type which is a cv­unqualified complete or incomplete object type or is void (3.9) has three corresponding cv­qualified versions of its type: a const­qualified version, a volatilequalified version, and a const­volatile­qualified version. The term object type (1.8) includes the cv­qualifiers specified when the object is created. The presence of a const specifier in a decl­specifier­seq declares an object of const­qualified object type; such object is called a const object. The presence of a volatile specifier in a decl­specifier­seq declares an object of volatile­qualified object type; such object is called a volatile object. The presence of both cv­qualifiers in a decl­specifier­seq declares an object of const­volatile­qualified object type; such object is called a const volatile object. The cv­qualified or cv­unqualified versions of a type are distinct types; however, they shall have the same representation and alignment requirements (3.9). 46)

      2. A compound type (3.9.2) is not cv­qualified by the cv­qualifiers (if any) of the types from which it is compounded. Any cv­qualifiers applied to an array type affect the array element type, not the array type (8.3.4).

      3. Each non­static, non­mutable, non­reference data member of a const­qualified class object is const­qualified, each non­static, non­reference data member of a volatile­qualified class object is volatile­qualified and similarly for members of a const­volatile class. See 8.3.5 and 9.3.2 regarding cv­qualified function types.

      4. There is a (partial) ordering on cv­qualifiers, so that a type can be said to be more cv­qualified than another. Table 6 shows the relations that constitute this ordering.

        Table 6 -  relations on const and volatile

        no cv­qualifier < const

        no cv­qualifier < volatile
        no cv­qualifier < const volatile
        const < const volatile
        volatile < const volatile

        5 In this International Standard, the notation cv (or cv1, cv2, etc.), used in the description of types, represents an arbitrary set of cv­qualifiers, i. e., one of {const}, {volatile}, {const, volatile}, or the empty set. Cv­qualifiers applied to an array type attach to the underlying element type, so the notation, "cv T," where T is an array type, refers to an array whose elements are so­qualified. Such array types can be said to be more (or less) cv­qualified than other types based on the cv­qualification of the underlying ele­ment types.
         
         

        3.10 Lvalues and rvalues

        [basic.lval]

        1. Every expression is either an lvalue or an rvalue.

        2. An lvalue refers to an object or function. Some rvalue expressions
          -- those of class or cv­qualified classtype
          -- also refer to objects. 47)

        3. [Note: some built­in operators and function calls yield lvalues. [Example: if E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the function

              int& f();

          yields an lvalue, so the call f() is an lvalue expression. ] ]
           


          Prec.     Page 56     Suiv.


          4 [Note: some built­in operators expect lvalue operands. [Example: built­in assignment operators all expect their left hand operands to be lvalues. ] Other built­in operators yield rvalues, and some expect them. [Example: the unary and binary + operators expect rvalue arguments and yield rvalue results. ] The discussion of each built­in operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue. ]

        4. The result of calling a function that does not return a reference is an rvalue. User defined operators are functions, and whether such operators expect or yield lvalues is determined by their parameter and return types.

        5. An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue (this includes the explicit creation of an object using functional notation (5.2.3)).

        6. Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue; see 4.1, 4.2, and 4.3.

        7. The discussion of reference initialization in 8.5.3 and of temporaries in 12.2 indicates the behavior of lvalues and rvalues in other significant contexts.

        8. Class rvalues can have cv­qualified types; non­class rvalues always have cv­unqualified types. Rvalues shall always have complete types or the void type; in addition to these types, lvalues can also have incomplete types.

        9. An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]

        10. Functions cannot be modified, but pointers to functions can be modifiable.

        11. A pointer to an incomplete type can be modifiable. At some point in the program when the pointed to type is complete, the object at which the pointer points can also be modified.

        12. The referent of a const­qualified expression shall not be modified (through that expression), except that if it is of class type and has a mutable component, that component can be modified (7.1.5.1).

        13. If an expression can be used to modify the object to which it refers, the expression is called modifiable. A program that attempts to modify an object through a nonmodifiable lvalue or rvalue expression is ill­formed.

        14. If a program attempts to access the stored value of an object through an lvalue of other than one of the fol­lowing
          types the behavior is undefined 48) :
          • the dynamic type of the object,
          • a cv­qualified version of the dynamic type of the object,
          • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
          • a type that is the signed or unsigned type corresponding to a cv­qualified version of the dynamic type of the object,
          • an aggregate or union type that includes one of the afore mentioned types among its members (including, recursively, a member of a subaggregate or contained union),
          • a type that is a (possibly cv­qualified) base class type of the dynamic type of the object,
          • a char or unsigned char type.

          Prec.     Page 57     Suiv.


          31) An object defined in namespace scope having initialization with side­effects must be initialized even if it is not used (3.7.1).

          32) The intent is to have operator new() implementable by calling malloc() or calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non­null pointer.

          33) On some implementations, it causes a system­generated runtime fault.

          34) For example, before the construction of a global object of non­POD class type (12.7).

          35) That is, an object for which a destructor will be called implicitlyÐ either either upon exit from the block for an object with automatic storage duration or upon exit from the program for an object with static storage duration.

          36) By using, for example, the library functions (17.4.1.2) memcpy or memmove.

          37) The intent is that the memory model of C++ is compatible with that of ISO/ IEC 9899 Programming Language C.

          38) The size and layout of an instance of an incompletely­defined object type is unknown. type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

          39) That is, large enough to contain any value in the range of INT_MIN and INT_MAX,as defined in the header <climits>.

          40) See 7.1.5.2 regarding the correspondence between types and the sequences of type­specifiers that designate them.

          41) This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer

          42) Using a bool value in ways described by this International Standard as '' undefined, '' such as by examining the value of an uninitialized automatic variable, might cause it to behave as if is neither truenor false.

          43) Therefore, enumerations (7.2) are not integral; however, enumerations can be promoted to int, unsigned int, long, or unsigned long, as specified in 4.5.

          44) A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)

          45) Static class members are objects or functions, and pointers to them are ordinary pointers to objects or functions.

          46) The same representation and alignment requirements are meant to imply interchangeability as arguments to functions, return values from functions, and members of unions.

          47) Expressions such as invocations of constructors and of functions that return a class type refer to objects, and the implementation can
          invoke a member function upon such objects, but the expressions are not lvalues.

          48) The intent of this list is to specify those circumstances in which an object may or may not be aliased