3.5 Program and linkage |
[basic.link] |
translationunit:
declarationseqopt
[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. ]
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]
void f()
{
struct A { int x; }; // no linkage
extern A a;
// illformed
typedef A B;
extern B b;
// illformed
}
--end example] This implies that names with no linkage cannot be used as template arguments (14.3).
3.6 Start and termination |
[basic. start] |
3.6.1 Main function |
[basic. start. 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 [argc1] as pointers to the initial characters of nullterminated 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. ]
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.
return 0;
3.6.2 Initialization of nonlocal objects |
[basic. start. init] |
[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 zeroinitialized. 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 implementationdefined 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;
int main() {
a.Use();
b.Use();
}
3.6.3 Termination |
[basic. start. term] |
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] |
-- static storage duration
-- automatic storage duration
-- dynamic storage duration
3.7.1 Static storage duration |
[basic.stc.static] |
3.7.2 Automatic storage duration |
[basic.stc.auto] |
3.7.3 Dynamic storage duration |
[basic.stc.dynamic] |
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 newexpression, deleteexpression or function call that refers to one of these functions without including the header <new> is wellformed. However, referring to std, std::bad_alloc, and std::size_t is illformed 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.
3.7.3.1 Allocation functions |
[basic.stc.dynamic.allocation] |
3.7.3.2 Deallocation functions |
[basic.stc.dynamic.deallocation] |
3.7.4 Duration of subobjects |
[basic.stc.inherit] |
3.8 Object Lifetime |
[basic.life] |
- storage with the proper alignment and size for type T is obtained, and
- if T is a class type with a nontrivial 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 nontrivial destructor (12.4), the destructor call starts, or
- the storage which the object occupies is reused or released.
-- the pointer is used to access a nonstatic data member or call a nonstatic 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]
- 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 toplevel cvqualifiers), 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();
// welldefined
}
return *this;
}
C c1;
C c2;
c1 = c2;
// welldefined
c1. f();
// welldefined; c1
refers to a new object
of type C
--end example]
class T { };
struct B {
~B();
};
void h() {
B b;
new (& b) T;
} // undefined behavior at block exit
--end 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] |
#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]
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]
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++;
// illformed: X is incomplete
arrp++;
// illformed: 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;
// illformed: different types
xp++;
// OK: X is complete
arrp++;
// illformed: UNKA can't be completed
}
--end example]
3.9.1 Fundamental types |
[basic.fundamental] |
3.9.2 Compound types |
[basic.compound] |
-- 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 nonstatic 45) class members, which identify members of a given type within objects of a given class, 8.3.3.
3.9.3 CVqualifiers |
[basic.type.qualifier] |
Table 6 - relations on const and volatile
no cvqualifier < volatile
no cvqualifier < 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 cvqualifiers, i. e., one of {const}, {volatile}, {const, volatile},
or
the empty set.
Cvqualifiers 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 soqualified.
Such array types can be said to be more (or less) cvqualified than
other types based on the cvqualification of the underlying element
types.
3.10 Lvalues and rvalues |
[basic.lval] |
int& f();
yields an lvalue, so the call f() is an lvalue expression. ] ]
4 [Note: some builtin operators expect lvalue operands.
[Example: builtin assignment operators all expect their left hand operands to be lvalues.
] Other builtin operators yield rvalues, and some expect them.
[Example: the unary and binary + operators expect rvalue arguments and yield rvalue results.
] The discussion of each builtin operator in clause 5 indicates whether it expects lvalue operands and whether it yields an lvalue.
]
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 nonnull pointer.
33) On some implementations, it causes a systemgenerated runtime fault.
34) For example, before the construction of a global object of nonPOD 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 incompletelydefined 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 typespecifiers 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