0% found this document useful (0 votes)
145 views

C++ Reference Manual

Manual of C++
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
145 views

C++ Reference Manual

Manual of C++
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 61
‘The C++ Programming Language — Reference Manual Bjarne Stroup AT&T Bell Laboratories Murray Hill, New Jersey 07974 ( ABSTRACT C++ is C extended with ciasses, inline functions, operator overloading, function name overloading, constant types, references, free store management, function argument checking, and a new function definition syntax. This manual wwas derived from the Unix System V C reference manual, and the general organi- zation and section numbering have been preserved whereever possible. The differ- ences between C++ and C ate summarized. Except for details like introduction of new keywords, C++ is a superset of C. An index and a table of contents are also provided. For a more readable presentation of most of the new features see Bjarne Stroustrup: “A C++ Tutorial’. ot Bjarne Stroustrup: "The C++ Programming Language - Reference Manual”. Both in this volume. CONTENTS oe Bp HEE HEGEL aye egg 6e: an ad pass wh hl Ho HAG a! anane 333593 sQRRRR828 Baaas 4.3, ‘Fundamental types 44° Derived types. $. OBJECTS AND LVALUES . 6. CONVERSIONS 8.5 Class declarations 4.2 Storage classes 8.6 Initialization 8.7 Type names 4.1 Scopes 8.2 ‘Type specifiers 83° Declarators 25 2a 62 6 6 6. 6. 6 7 7, 7. 7 7. 7 7. 7 1 7. 7 1 7. 1 1 2, LEXICAL CONVENTIONS . 3. SYNTAX NOTATION 4, WHAT'S IN A NAME? 1. INTRODUCTION 8. DECLARATIONS . Compound statement, or block 3 Conditional statement 9.4 While statement... 9.5 Dostatement . 9.6 For statement. . 9.7 Switch statement « ‘Typedet 8.10 Enumeration declarations. 8.9 Overloaded function names 88 92 93 8.11 Asm declaration . 9. STATEMENTS . 9.1 Expression statement 9.13, Null statement 9.15 Declaration statement 10. EXTERNAL DEFINITIONS 9.14 Delete statement « 30:1 Function definitions... 10.2 External data definitions. 11. SCOPERULES. . . . . 12. COMPILER CONTROL LINES 32.1 Token replacement 144 Explicit pointer conversions 15. CONSTANT EXPRESSIONS 14.1 Classes. 33, IMPLICIT DECLARATIONS 14. TYPES REVISITED . . . 162 Functions. 143 Arrays, pointers, and subscripting 16. PORTABILITY CONSIDERATIONS. . . . - 17, FREE STORE 19.2 Summary of incompatibilities . 18S Preprocessor 2. 5. st 19.3. Anachronisms 19, DIFFERENCES FROM C 18.4 External definitions . 19.1 Extensions. . I i ! ‘The C++ Programming Language — Reference Manual Bjarne Stroustrup ATAT Bell Laboratories Murray Hill, New Jersey 07974 1, INTRODUCTION ‘This manual describes the C++ programming language. C++ is C as described in the C bookt extended with classes, inline functions, operator overloading, function name overioading, constant types, references, free store management, function argument checking, md a new function definition syntax. The differences between C++ and C are summarized in §19. This manual describes the language as of October 1984. 2. LEXICAL CONVENTIONS ‘There are six classes of tokens: identifiers, keywords, constants, strings, operators, and other separators. Blanks, tabs, new-lines, and comments (collectively, “white space") as described ‘below are ignored except as they serve to separate tokens. Some white space is required to separate otherwise adjacent identifiers, keywords, and constants. Af the input stream has been parsed into tokens up to a given character, the next token is taken to {include the longest string of characters which could possibly constitute a token, 2.1 Comments ‘The characters /« introduce a comment, which terminates with the characters «/, Comments do ‘not nest. 2.2 Identifiers (Names) ‘An identifier is an arbitrarily long sequence of letters and Jeter; the underscore counts as a letter. Upper- and lower-case lewers are different. 2.3 Keywords ‘The following identifiers are reserved for use as keywords, and may not be used otherwise: am axto break case chaz class const default delete do double else = enum extern float friend goto if inline int long operator overload public register return short static struct switch this typedet union - unsigned virtual void while 24 Constants ‘There are several kinds of constants, as listed below. Hardware characteristics that affect sizes are summarized in §2.6. 2.4.1 Integer constants ‘An integer constant consisting of a sequence of digits is taken to be octal if it begins with 0 (digit zero), decimal otherwise. The digits 6 and 9 are not octal digits. A sequence of digits preceded by x or Ox (digit zero) is taken to be a hexadecimal integer. The hexadecimal digits include a or A through £ or F with values 10 through 15. A decimal constant whose value exceeds the largest This manual is organized tke the sefeence mamual in The C Programming Language by Brian W. ‘Kemighan and Dennis M. Ritchie, Prentice Hall, 1978. ad . C++ Reference Manual 2 signed integer is taken to be 1ong; an octal or hex constant which exceeds the largest unsigned integer is likewise taken to be 1ong; otherwise integer constants are taken to be int. 2.4.2 Explicit long constants ‘A decimal, octal, or heradecimal integer constant immediately followed by 1 (letter ell) or Lis a Jong constant. 2.4.3 Character constants A character constant is a character enclosed in single quotes, as in ‘x’. The value of a character constant is the numerical Value of the character in the machine's character set. Character constants are taken to be int. Certain non-graphic characters, the single quote ‘, and the backslash \, may be represented according to the following table of escape sequences: newline NL) \n horizontal tab Xt Vertical tab w backspace \» carriage return x form feed \ backslash Y single quote Y bit pattern Nadd “The escape \ddd consists of the backslash followed by 1, 2, or 3 octal digits which are taken 10 specify the value of the desired character. A special case of this construction is \O (not followed by a digit), which indicates the character NUL. If the character following a backslash is not one of ‘those specified, the backslash is ignored. 2.4.4 Floating constants A floating constant consists of an integer par, a decimal point, a fraction part, ane or 2, and an ‘optionally signed integer exponent. The integer and fraction parts both consist of a sequence of digits. Either the integer part or the fraction part (not both) may be missing; either the decimal point or the e (2) and the exponent (not both) may be missing. A floating constant which cannot be represented exactly as a single-precision float is taken to be double-precision; see $2.6. 2.4.5 Enumeration constants Names declared as enumerators (see §8.5) are constants of type int. 2.4.6 Declared constants ‘An object (§5) of any type can be specified to have a constant value throughout the scope (§4.1) of its name. For pointers the const declarator (§8.3) is used to achieve this; for non-pointer objects the specifier const (§8.2) is used. 2.5 Strings ‘A string is a sequence of characters surrounded by double quotes, as in "...". A string bas type “array of characters" and storage class static (see §4 below), and is initialized with the given characters. All strings, even when written identically, are distinct. The compiler places a null byte No at the end of each string so that programs which scan the string can find its end. In a string, the double quote character * must be preceded by a \; in addition, the same escapes as described for character constants may be used. Finally, # new-line may occur only immediately following a \; thea both the \ and the new-line are ignored. BA 9855 CO C++ Reference Manual 3 2.6 Hardware characteristics ‘The following table summarizes certain hardware properties that vary from machine to machine. DEC VAX Motorola 68000 ‘BM370ATAT 3B ASCH ASCH EBCDIC ASCH. char 8 bits 8 bits B bis 8 bits int 2 6 2 2 short 16 16 % | 6 long 32 2 2 32 float 32 2 mi double “ “a “a “ pointer 2 2. mu 32 float range £10*38 #10738 oo ee double range | +10*3% £1038 £102 | £1928 field type signed unsigned | unsigned | unsigned field order | right-toreft | lef-toright | left-to-right | left-to-right char | signed unsigned | unsigned | unsigned 3, SYNTAX NOTATION In the syntax notation used in this manual, syntactic categories are indicated by italic type, and eral words and characters in constant width type. Alternatives are listed on separate lines. ‘An optional terminal or non-terminal symbol is indicated by the subscript “opt,” so that { expression,y, } indicates an optional expression enclosed in braces. The syntax is summarized in §19. 4, WHAT'S IN A NAME? ‘A name denotes an object, a function, a type, or a value. A name can only be used within a region of program text called its scope. A name has a type which determines its use. An object is a region of storage. An object has a storage class which determines its lifetime. The meaning of the Values found in an object is determined by the type of the name used to access it. 4.1, Scopes ‘There are four kinds of scope: local, file, program, and class. Local: A name declared in a block is local o that block and can only be used in it after the point of declaration and in blocks enclosed by it. Exceptions are labels (§9.12) which can be used anywhere in the function in which they are declared, and function names which belong to the file or program scope. Names of formal parameters for a function are treated as if ‘they were declared in the outermost block of that function. File: A name declared outside any block (§9.2) or class ($8.5) can be used in the file in which it is declared after the point of declaration. It is not accessible from other files in a ‘multifile program unless it is explicitly declared extern. Program: A name declared extern is common to every file in a multifile program, to that a eclaration of that name in another file refers to the same object (§5), function (610.1), type ($8.7), or value (§8.10). Class: The name of 1 class member is local to its class and can only be used either in a member function of that class, for an object of its class using the . operator (§7.1), of for a pointer to an object ofits class using the -> operator (§7.1). Stic cass members (18.5.1) and function members can also be referred to where the name of their class is in scope by using the : operator (47.1). C++ Reference Manual 4 ‘Anname may be hidden by an explicit declaration of that same name in a block or class. A name in a block or class can only be hidden by a name declared in an enclosed block or class. A hidden ‘non-local name can still be used when its scope is specified using the :: operator; see §7.1. 4.2 Storage classes ‘There are two declarable storage classes: automatic and static, ‘Automatic objects are local to each invocation of a block and are discarded upon exit from it. Static objects exist and retain their values throughout the execution of the entire program. Some objects are not associated with names and their lifetimes are explicitly comolled using the new and delete operators; see §7.2, §9.14, and §17. 4,3 Fundamental types Objects declared as characters (char) are large enough to store any member of the implementation’s character set, and if a genuine character from that character set is stored in a character variable, fs value is equivalent to che integer code for that character. Oxher quantities ‘may be stored into character variables, but the implementation is machine-dependent. Up to three sizes of integer, declared short int, int, and long int, are available, Longer integers provide no less storage than shorter ones, but the implementation may make either short integers, or long integers, or both, equivalent to plain integers. “Plain” integers have the natural size suggested by the host machine architecture; the other sizes are provided to meet special needs. ‘Each enumeration (§8.9) is a set of named constants. The properties of an enum are identical to those of an int. Unsigned integers, declared unsigned, obey the laws of arithmetic modulo 2" where n is the ‘number of bits in the representation. Single-precision floating point (€1oat) and double-precision floating point (double) may be synonymous in some implementations. ‘Because objects of the foregoing types can usefully be interpreted as numbers, they will be referred 10 88 arithmetic types. Types char, int of all sizes, and enum will collectively be called integral types. float and double will collectively be called floating types. ‘The void type specifies an empty set of values; see $6.7. 4.4 Derived types ‘Besides the fundamental arithmetic types there is a conceptually infinite number of derived types constructed from the fundamental types in the following ways: arrays of objects of a given type; functions which take arguments of given types and return objects of a given type; ‘pointers to objects of a given type; references to objects of a given type; constants which are values of a given ‘ype; classes containing a sequence of objects of various types, a set of functions for manipulating these objects, and a set of restrictions on the access to these objects and functions; -sructures which are classes without access restrictions; unions which are structures capable of containing objects of different types at different times. In general these methods of constructing objects can be applied recursively. i C++ Reference Manual 5 S. OBJECTS AND LVALUES ‘An object is a region of storage; an Ivalue is an expression referring to an object. An obvious ‘example of an Ivalue expression is the name of an object. There are operators which yield Ivalues: for example, if £ is an expression of pointer type, then «2 is an Ivalue expression referring to the object to which & points. The name “Wvalue” comes from the assignment expression £1 = £2 in which the left operand £1 must be an Ivalue expression. The discussion of each operator below indicates whether it expects Ivalue operands and whether it yields an Ivalue. 6. CONVERSIONS ‘A number of operators may, depending on their operands, cause conversion af the value of an operand from one type to another. This section explains the result to be expected from such conversions. §6.6 summazizes the conversions demanded by most ordinary operators; it will be supplemented as required by the discussion of each operator. $8.5,6 describes user-defined conversions, 6.1 Characters and integers ‘A character or a short integer may be used wherever an integer may be used. In all cases the value is converted to an integer. Conversion of a shorter integer to a longer always involves sign extension; integers are signed quantities. Whether or not sign-emtension occurs for characters is machine dependent; see §2.6. The more explicit type unsigned char forces the values to range from 0 to a machine dependent maximum. On machines that teat characters as signed, the characters of the ASCII set are all positive. ‘However, a character constant specified with an octal escape suffers sign extension and may appear ‘negative; for example, ’\377" has the value -1. ‘When a longer integer is converted to a shorter or to a char, itis truncated on the left; excess bits are simply discarded. 6.2 Float and double Floating arithmetic is carried out as if in double-precision. Conversions between single-precision and double-precision floating-point numbers are as mathematically correct as the hardware allows. 6.3. Floating and integral Conversions of floating values to integral type tend to be machine-dependent; in particular the irection of truncation of negative numbers varies from machine to machine, The result is undefined ifthe value will not fit in the space provided. ‘Conversions of integral values to floating type are well behaved. Some loss of precision occurs if the destination lacks sufficient bits. 6.4 Pointers and integers ‘An expression of integral type may be added to or subtracted from a pointer; in such a case the first is converted as specified in the discussion of the addition operator. ‘Two pointers to objects of the same type may be subtracted; in this case the result is canverted to am int or a long dependent on the machine; see §7.4. 6.5. Unsigned ‘Whenever an unsigned integer and a plain integer are combined, the plain integer is converted to unsigned and the result is unsigned. The value is the least unsigned integer congruent to the signed integer (modulo 2*482), In a 2's complement representation, this conversion is ‘conceptual and there is no actual change in the bit pattern. C++ Reference Manual 6 ‘When an unsigned integer is converted to long, the value of the result is the same numerically as that of the unsigned integer. Thus the conversion amounts to padding with zeros on the left. 6.6 Arithmetic conversions ‘A great many operators cause conversions and yield result types in a similar way. This pattern will be called the “usual arithmetic conversions.” First, any operands of type char, unsigned char, or short are converted to int, and any of type float is converted to double. ‘Then, if either operand is double, the other is converted to double and that is the type of the result, Otherwise, if either operand is unsigned iong the other is converted to unsigned long and that is the type of the result. Otherwise, if either operand is 1ong, the other is converted to ong and that is the type of the result. Otherwise, if either operand is unsigned, the other is converted to unsigned and that is the type of the result. ‘Otherwise, both operands must be int, and that is the type of the result. 6.7 Void The (nonexistent) value of a void object may not be used in any way, and neither explicit nor implicit conversions may be applied. Because a void expression denotes a nonexistent value, such an expression may be used only as an expression statement (§9.1) or as the left operand of a comma expression (§7.15). ‘An expression may be converted to type void by use of a cast. For example, this makes explicit the discarding of the value of a function call used as an expression statement. ‘A object of type voide (pointer to void) can be used to point to objects of unknown type. 7. EXPRESSIONS ‘The precedence of expression operators is the same as the order of the major subsections of this section, highest precedence firs. Thus, for example, the expressions referred to as the operands of + ($7.4) are those expressions defined in $§7.1-7.4. Within each subsection, the operators have the same precedence. Left- or right-associatvity is specified in each subsection for the operators. discussed therein. The precedence and associativity of all the expression operators is summarized in the grammar of §18. Otherwise the order of evaluation of expressions is undefined. In particular the compiler considers ftself free to compute subexpressions in the order it believes most efficient, even if the subexpressions involve side effects. The order in which side effects take place is unspecified. Expressions involving a commutative and associative operator (+, +, & 1, *) may be rearranged arbitrarily, even in the presence of parentheses; to force a particular order of evaluation an explicit temporary must be used. ‘The handling of overflow and divide check in expression evaluation is machine-dependent. Most existing implementations of C++ ignore integer overflows; treatment of division by 0, and all floating-point exceptions, varies between machines, and is usually adjustable by a library function. In addition to the standard meanings described in §7.2-7.15 operators may be overloaded, that is siven meanings when applied to user-defined types; see §7.16. ¢ C++ Reference Manual 7 7.1 Primary expressions Primary expressions involving ., ->, ::, subscripting, and function calls group left-to-right. a: densfier operator function name ppedef-name : identifier ___ypedef-name : + operator function-name rimary-expression: id 24 idensifier constant snring vaie (expression ) ‘rimary-axpression | exprestion | rimary-espression ( expressionist, ) Primary-expression « id Primary-expression => id expressionclis: expression expressionclis , expression ‘An identifier is a primary expression, provided it has been suitably declared as discussed below. Its type is specified by its declaraion. If the type of the identifier is “array of ...", however, then the Value of the identifier-expression is a pointer to the first object in the array, and the type of the expression is “pointer to ...”. Moreover, an array identifier is not an Ivalue expression. Likewise, an identifier which is declared “function returning ...”, when used except in the function-name position of a call, is converted to ‘‘pointer to function returning ...”. An operator- ‘funcrlon-name is an identifier with & special meaning; see 7.16 and §8.5.10. ‘The operator :: followed by an identifier is a primary expression, provided the identifier has been suitably declared in the fle or program scope (84.1). is type is specified by the declaration of the ‘identifier. It allows an object to be referred to by name even if its identifier has been redefined in a local scope. A ppedef-name (58.8) followed by :+ folowed by an identifier is a primary expression. The ‘ppedef-name must denote a class (§8.5) and the identifier must denote a member of that class. Its ‘ype is specified by the declaration of the identifier. ‘A constant is a primary expression. Its type may be int, long, or double depending on its form. ‘A string is a primary expression. Its type is originally “array of char”; but following the same rule given above for identifiers, this is modified to “pointer to char” and the result is a pointer to the first character in the string. (There is an exception in certain initializers; see $8.6.) ‘The keyword this is a primary expression in the body of a member function (see $8.5). There it refers to the object for which the member function was invoked. ‘A parenthesized expression is a primary expression whose type and value are identical to those of the unadorned expression. The presence of parentheses does not affect whether the expression is an value. ‘A primary expression followed by an expression in square brackets is a primary expression. ‘The {intuitive meaning is that of a subscript. Usually, the primary expression has type “pointer to ...", the subscript expression is int, and the type of the result is “..."". The expression 211221 is CO C++ Reference Manual 8 identical (by definition) to «((B1)+(22)). All the clues needed to understand this notation are contained in this section together with the discussions in §§ 7.1, 7.2, and 7.4 on identifiers, «, and + respectively; §14.3 below summarizes the implications. ‘A function call is # primary expression followed by parentheses containing @ possibly empty, comma-separated list of expressions which constitute the actual arguments to the function. ‘The primary expression must be of type “function returning ...", and the result of the function call is of type “...". A hitherto unseen identifier followed immediately by a left parenthesis is contextually declared to represent a function returning an integer. Its argument type will be declared to that of the argument list of the call. ‘The actual arguments are compared with the formal arguments and conversions are performed as if the formal argument were initialized with its actual argument (see $8.6). In preparing for a call to a function, a copy is made of each actual parameter. A function may change the values of its formal parameters, but these changes cannot affect the values of the actual parameters. On the other hand, it is possible to pass a pointer or a reference on the understanding ‘that the function may change the value of the object to which the pointer or reference points. An array name is a pointer expression. ‘A function may be declared to accept fewer arguments or more arguments than are specified in the function declaration; see $8.4. Any actual argument of type float for which there is no formal argument are converted to double before the call; any of type char or short are converted to int; and as usual, array names are converted to pointers. ‘The order of evaluation of arguments is ‘undefined by the language; take note that the various compilers differ. Recursive calls to any function are permitted, ‘A primary expression followed by a dot followed by an idemtifier (or an identifier qualified by a ‘ypedef-name using the :: operator) is an expression. The first expression must be a class object, and the identifier must name a member of that class, The value is the named member of the object, and it is an Ivalue if the first expression is an Ivalue, Note that ‘class objects” can be structures ($8.5.11) and unions (§8.5.12). ‘A primary expression followed by an arrow (->) followed by an identifier (or an identifier qualified by a typedef-name using the :: operator) is an expression. The first expression must be a pointer 10 a class object and the identifier must name a member of that class. The result is an Ivalue referring to the named member of the class to which the pointer expression points. Thus the expression B1~>MOS is the same as (#21).HOS, Classes are discussed in $8.5. fa primary expression yields a value of type “reference to..." (see 8.4 and §8.6.3) that value is immediately dereferenced so that the value of the expression is the object denoted by the reference. If this object is also a reference, it too will be dereferenced, and so on. A reference can be thought of as a name of an object; sec §8.6.3. 7.2. Unary operators ‘Expressions with unary operators group right-to-left. C++ Reference Manual 9 unary-expression: unary-operator expression expression ++ expression == Cape-name ) expression simple-type-name ( expressionlist ) sizeof expression sizeof ( npe-name ) Rew ppe-name new ( ppe-name ) unary-operaior: one of Can a ‘The unary « operator means indirection: the expression must be a pointer, and the result is an Walue referring to the object to which the expression points. If the type of the expression is “pointer to ...", the type of the result is ‘The result of the unary & operator is a pointer to the object referred to by the operand. The operand must be an Ivalue. If the type of the expression is “...", the type of the result is ‘The result of the unary ~ operator {s the negative of its operand. The operand must be of imegral type. The usual arithmetic conversions are performed. The negative of an unsigned quantity is computed by subtracting its value from 2", where n is the number of bits in an int. There is no ‘unary + operator. ‘The result of the logical negation operator 1 is 1 if the value of its operand is 0, 0 if the value of its operand is non-zero. The type of the result is int. It is applicable to any arithmetic type or to pointers. ‘The - operator yields the one’s complement of its operand. The usual arithmetic conversions are performed. The type of the operand must be integral. ‘The operand of prefix ++ is incremented. The operand must be an Walue. The value is the new value of the operand, but is not an Ivalue. The expression ++x is equivalent to x+=1. See the discussions of addition (87.4) and assignment operators (§7.14) for information on conversions. ‘The operand of prefix -~ is decremented analogously to the prefix ++ operator. ‘The value obtained by applying a postfix ++ is the value of the operand. The operand must be an Ivalue, After the result is noted, the object is incremented in the same manner es for the prefix ++ operator. The type of the result is the same as the type of the operand. ‘The value obtained by applying a postfix ~~ is the value of the operand. The operand must be an IWalue, After the result is noted, the object is decremented in the manner as for the prefix -- operator. The type of the result isthe same as the type of the operand. A. simple-tpe-name (§8.2) followed by 8 parenthesized expression causes the value of the ‘expression to be converted to the named type. To express conversion to a type that does not have ‘simple name the npe-name (§8.7) must be parenthesized; in this case the expression need not be parenthesized. This construction is called a cast. The method for defining conversions for usex- defined types (classes) is described in §8.5.5 and §8.5.6. For user-defined types an expression list, rather than a simple expression, can be used; see 88.5.5. ‘The sizeof operator yields the size, in bytes, of its operand. (A byte is undefined by the language except in terms of the value of sizeof. However, in all existing implementations a byte 5s the space required to hold a char.) When applied to an atray, the result is the total number of bytes in the array. The size is determined from the declarations of the objects in the expression. ‘This expression is semantically an unsigned constant and may be used anywhere a constant is C++ Reference Manual 10 required. Its major use is in communication with routines like storage allocators and VO systems, ‘The sizeof operator may also be applied to a parenthesized type name, In that case it yields the size, in bytes, of an object of the indicated type. ‘The new operator creates an object of the npe-name (see $8.7) to which itis applied. The lifetime of an object created by new is not restricted to the scope in which it is created. The new operator returns a pointer to the object it created. When applied to an object of type 7 it therefore generally returns a Value of type T+. However, the type yielded for an array type T{] is T+. For example, both new int and new int[ 10) retum an int+. See §17 for detals of how the free store is managed. 7.3. Multiplicative operators ‘The multiplicative operators «, /, and % group leftto-right. ‘The usual arithmetic conversions are performed. ‘mathiplicative-expression: ‘expression + expression expression / expression expression % expression ‘The binary » operator indicates multipication. The + operator is associative and expressions with several multiplications at the same level may be rearranged by the compiler. ‘The binary / operator indicates division. When positive integers are divided truncation is toward , but the form of truncation is machine-dependent if either operand is negative. On all machines covered by this manual, the remainder has the same sign as the dividend. It is always true that (a/b)eb + aXp is equal to a (if Dis not 0). ‘The binary % operator yields the remainder from the division of the first expression by the second. ‘The usual arithmetic conversions are performed. The operands must not be floating. 7.4 Additive operators The additive operators + and - group left-to-right. The usual arithmetic conversions are performed. There are some additional type possibilities for each operator. addiive-expression: expression + expression expression ~ expression ‘The result of the + operator is the sum of the operands. A pointer to an object in an array and a value of any integral type may be added. The latter isin all cases converted to an address offset by multiplying it by the length of the object to which the pointer points. The result is a pointer of the same type as the original pointer, and which points to another object in the same array, appropriately offset from the original object. Thus if P is a pointer to an object in an array, the expression P+1 is a pointer to the next object in the array. No further type combinations are allowed for pointers. ‘The + operator is associative and expressions with several additions at the same level may be rearranged by the compiler. ‘The result of the - operator is the difference of the operands. The usual arithmetic conversions are performed. Additionally, a value of any integral type may be subtracted from a pointer, and then the same conversions as for addition apply. If two pointers to objects af the same type are subtracted, the result is converted (by division by the length of the object) to an integer representing the number of objects separating the pointed-10 objects. Depending on the machine the resulting integer may be of type int or type long; see §2.6. This conversion will in general give unexpected results unless the pointers point to objects in C++ Reference Manzal n the same array, since pointers, even to objects of the same type, do not necessarily differ by a multiple of the object-length. 7.5 Shift operators ‘The shift operators << and >> group leh-to-tight. Both perform the usual arithmetic conversions con their operands, each of which must be integral. ‘Then the right operand is converted to dnt; the type of the result is that of the left operand. The result is undefined if the right operand is negative, or greater then or equal to the length of the object in bits. shifexpression: expression << expression expression >> expression The value of B1 << 22 is B4 (interpreted as a bit pattern) ief-shifted #2 bits; vacated bits are 0- filled. The value of £1 >» B2 is £1 right-shifted 2 bit positions. The right shift is guaranteed to be logical (O-fil) if £1 is unsigned; otherwise it may be arithmetic (Gil by a copy of the sign bi). 7.6 Relational operators ‘The relational operators group left-to-right, but this fact is not very useful; acbec does not mean what it seems to. relatonal-expression: expression < expression expression » expression expression expression ‘The operators < (less than), > (greater than), <= (less than or equal to) and >= (greater than or ‘equal to) all yield 0 if the specified relation is false and 1 if it is true. The type of the result is int. The usual arithmetic conversions are performed. Two pointers may be compared; the result depends on the relative locations in the address space of the pointed-to objects. Pointer ‘comparison is portable only when the pointers point to objects in the same array. 7.7 Equality operators equality-expression: expression =x expression expression |= expression ‘The == (equal to) and the 1= (aot equal to) operators are exactly analogous to the relational ‘operators except for their lower precedence. (Thus a elassrhead { member-lisQh pablic + members, > ont class-head: ‘ager Identifier, asgr idenifer®?" + public, npedefname ager: class struct union C++ Reference Manual 20 A structure is a class with all members public; see §8.5.8. A union is a structure which holds only fone member at a time; see §8.5.12. A member-list may declare data, function, class, typedef, enum, and field members. Fields are discussed in §8.5.13. A member-list may also contain declarations adjusting the visibility of member names; see §8.5. ‘member-lst: member declaration member-lisy, ‘member-declaration: decl-specifiers,p, member-declarator initializer, ; face ” mamber-declarator: declarator denier p, !constan-espression ‘Members that are class objects must be objects of previously declared classes. In particular, a class ‘02 may not contain an object of class ¢2, but it may contain a pointer to an object of class o1. ‘The member names in different classes do not conflict with each other or with ordinary variables. Only declarations of static members (§8.5.1) may contain intializers. A simple example of a struct declaration is struct tnode ( char tword[20]; which contains an array of 20 characters, an integer, and two pointers to similar structures. Once this declaration has been given, the declaration tnode s, *8p; declares 8 to be a tnode and sp to be a pointer toa tnode. With these declarations sp->count refers to the count field of the structure to which sp points; sitet refers to the left subtree pointer of the structure a; and s.right->tword[0] refers to the first character of the tword member of the right subtree of a. 8.5.1 Static members A data member of a class may be static; function members may not. Members may not be auto, register, or extern. There is only one copy of a static member shared by all objects of, the class in a program. A static member men of class c2 can be referred to as cl::men, that is ‘without referring to an object. It exists even if no objects of class ©2 have been created. 8.5.2. Member functions ‘A function declared as a member (without the friend specifier (68.5.9) is called a member function, and is called using the class member syntax (67.1). For example: a C++ Reference Manual a struct tnode ( char tword[20]; int count: tnode eleft; tnode «right; void set(chare, tnodes 1, tnodes r); H tnode nt, ni niet ("asde”,£n2,0)5 na -set("gh3k", 0,0); ‘The definition of a member function is considered to be within the scope of its class. This means ‘that it can use names of its class directly. If the definition of a member function is lexically outside the class declaration the member function name must be qualified by the class name using the rypedef-name.simple-dname notation; see §8.3.3. Function definitions are discussed in §10.1. void tnode.set (char w, tnodes 1, tnodes r) ( count = strien(w); Af (sizeof (tword)men are synonymous in a class c2 member function (unless mem has been ‘used a8 the name of a local variable in an intermediate scope). ‘A member function may be defined ($10.1) in the class declaration, Placing a member function definition in the class declaration is just a shorthand for declaring it in the class declaration and then defining it inline (§8.1) just after the class declaration. For example: int bi struct x { int £() { return >: int by h int b; struct x { int £0; int io inline x.£() { return b; } o C++ Reference Manual 2 ‘The specifier overload (§8.2) need not be used for member functions: if a name is declared to denote several functions in a class itis overloaded (sce §8.9). 1k is legal to apply the address-of operator to a member function. However, the npe of the resulting pointer to function is undefined, so that any use of itis implementation dependent. 8.5.3 Derived classes In the construct ager idenifier + pablicgy, npedef-name the npedef-name must denote a previously declared class, which is called a base class for the class being declated. ‘The latter is said to be derived from the former. For the meaning of public see $8.5.8. The members of the base class can be referred to as if they were members of the derived class itself, except when a base member name has been re-defined in the derived class; in this case the npedef-name::identifier notation (§7.1) can be used to refer to the hidden name. For example: struct base ( int a, bs struct derived : public base ( int b, ¢ h derived 4; assigns to the four members of 4. ‘A derived class can itself be used as a base class. It is not possible to derive from a union (585.12). Assignment is not implicitly defined (see §7.14 and $14.1) for a objects of a class derived from a class for which operators() has been defined (§8.5.10). 8.5.4 Virtual functions If a base class base contains a virtual (68.1) function vf, and a derived class derived also contains a fonction vE then a call of vf for an object of class derived invokes derived: :vé. For example: struct base { virtual void vf(); void £005 struct derived : void vf( void £1); public base { h C (C++ Reference Manual B derived 4; bases bp = 6d; bp->vE bpert0)s ‘The calls invoke derived: :vf and base: :£, respectively for the class derived object named 4. That is, the interpretation of the call of a virtual function depends on the type of the object for which it is called, whereas the interpretation of a call of a non-virtual member function depends only on the type of the pointer denoting that object. This implies that the type of objects of classes ‘with virtual functions and objects of classes derived from such classes can be determined at run time. Af a derived class has 8 member of the same name as a virtual function in a base class the its type ‘must be the same in both classes. A virtual function cannot be a friend (§8.5.9). A function £ in a class derived from a class which has a virtual function # is itself considered virtual. A virtual function in a base class must be defined. A virtual function which has been defined in a base class ‘need not be defined in a derived class. In that case, the function defined for the base class is used in all calls. 8.5.5 Constructors ‘A member function with the same mame as its class is called a constructor. A constructor has no return value type; it is used to construct values of its class type. A constructor can be used to create new objects of its type, using the syntax ‘ppedef-name ( arguments, ) For example, complex zz = complex(1, 2.3); oprint( complex(7.8, 1-2) 1; Objects created in this way are unnamed (unless the constructor was used as an initializer as for zz above), with their lifetime limited to the scope in which they are created. They can often be considered constants of their type. If a class has a constructor it is called for each object of that class before any use is made of the object; see §8.6. A constructor may be overload, but not virtual of friend. If a class has a base class with a constructor, the constructor for the base ciass is called before the constructor for the derived class, The constructors for member objects, if any, are executed after the constructor for the base class and before the constructor for the object containing them. See §10.1 for an explanation of how arguments can be specified for a base class constructor, and see §17 for an explanation of how constructors can be used for free storage management. ‘An object of a class with a constructor canam be a member of a union. 8.5.6 Conversions ‘A constructor taking a single argument specifies a conversion from its argument type to the type of its class. Such canversions are used implicitly in addition to the usual arithmetic conversions. An assignment ro an object of class x is therefore legal if either the assigned value is an x, or if a conversion has been declared from the type of the assigned value to x. Constructors are used similarly for conversion of function arguments (87.1) and initializes ($8.6). For example: ny C++ Reference Manual 24 class x { ... x(int); }5 £(x arg) ( xa Peaexi ey Pe ae XZ) 7 Zo £(X(3)) 97 £03 y ‘When no constructor for class x is found which accepts the assigned type, no attempt is made to find other constructors to convert the assigned value into a type which would be acceptable to a ‘constructor for class x. For example: lags x { ... x(int); } clase x (00. X02); 5 Yast 7» Alleged: ¥(x(1)) not tried «/ ‘A member function of a class x with a name of the form conversion-function-name: operator pe specifies a conversion from pe to x. It will be used implicitly like the constructors above, or it can be called explicitly using the cast notation. For example: class x { operator int(); Kas dnt 4 © dne(a); i= Cintas tea In all three cases the value assigned will be found by a call of the function x: :operator int(). ‘A user defined type conversion is implicitly applied only if it is unique; see $8.9. Note that if a class x has a conversion to an integral or pointer type declared, an Xx can be wed whereever an expression of such a type is required. For example xa, int d= (a) ? tea int J = (aBEb) ? arb 8.5.7 Destructors ‘A member function of class c1 named ~c1 is called a destructor. A destructor has no return value and takes no arguments; itis used to destroy values of type ¢1 immediately before the object containing them is destroyed. A destructor cannot be overload or friend. ‘The destructor for a base class is executed after the destructor far its derived class. Destructors for member objects are executed before the destructor for the object they are members of. See §17 for an explanation of how destructors can be used for free storage management. An object of a class with a destructor cannot be the member of a union. 8.5.8 Visibility of member names ‘The members of a class declared with the keyword class are private, that is, their names can oly be used by member functions (§8.5.2) and friends (see §8.5.20), unless they appear after the C++ Reference Manual 25 “public” label; in that case they are public. A public member can be used in any function. A struct is a class with all members public; see §8.5.11. If the keyword public precedes the base class name in the declaration of a derived class the public members of the base class are public for the derived class; if not, they are private. A public member men of a private base class base can be declared to be public for the derived class by a declaration of the form ypedef-name . identifier + where the npedef-name denotes the base class and the identifier is the name of a member of the base class. Such a declaration must occur in the public part of the derived class. Consider ela publi int by oF int BEC: derived : base ( int 4; pubiie: int dnt af0; h Ant ef (derived&); ‘The extemal function ef can use only the names c, e, and af. Being a member of derived, the function 4f can use the names b, ¢, bf, d, e, and df, but not a. Being a member of base, the function bf can use the members a, b, ¢, and bf. 8.5.9 Friends {A friend of a class is a non-member function which may use the private member names from the dass. A friend is not in the scope of a class and is not called using the member selection syntax (unless it itself is the member of some class). The following example illustrates the differences between members and friends: class private { int friend void friend_set (privates, int); public: ‘void member_eet (int); h void friend_set (privat P, int 4) { perms 4; } void private.menber_set(int 1) { a= 4; } private obj; friend_set(Sobj, 10); obj -member_set (10); C++ Reference Manual 26 ‘When a friend declaration refers to an overloaded name or operator only the function specified by the argument types becomes a friend. A member of a class c11 can be the friend of a class 22. For example class cl2 { friend chart cl foo int); a All the functions of a class ¢11 can be made friends of a class ©12 by a single declaration class c12 { friend elt ; Placing the definition of a friend function in a class declaration is a shorthand for declaring it and then defining it nine just as for member functions; see $8.5.2. 8.5.10 Operator functions ‘Most operators can be overloaded to take class object operands. ‘operator function-name: operator operator operator: one of new delete toe ee wR MR Ee ee er er tebe te eee cee ede eee ee ee) ‘The last rwo operators are function call and subscripting. An operator function (except operator new() and operator delete( ); see §17) must either be a member function or take at least one argument of clsss type. See also $7.16. 8.5.11 Structures A structure is a class with all members public. That is struct # (66. 5 is equivalent to class s { public: ... 35 ‘A structure may have member functions (including constructors and destructors). 8.5.12 Unions Avunion may be thought of as a structure all of whose member objects begin at offset 0 and whose size is sufficient to comtain any of its member objects. At most one of the member objects can be stored in a union at any time. A union may have member functions (including constructors and destructors). It is not possible to derive a class from a union. An object of a class with a constructor or a destructor cannot be a member of a union. Avunion of the form union { member-list } is called an anonymous union; it defines an unnamed object. The names of the members of an C++ Reference Manual a anonymous union must be distinct from other names in the scope where the union is declared; can be used directly in that scope without using the usual member access syntax (§8.5). For example union { int a; ehare ps}; ast pe Tasee* Here a and p are used like ordinary (non-member) variables, but since they are union members they have the same address. 8.5.13 Bit fields A member-declarator of the form ensifiersy,* constant-espresson specifies a field; its length is set off from the field name by a colon. Fields are packed into ‘machine integers; they do not straddle words. A field which does not fit into the space remaining {in an integer is put into the next word. No field may be wider than a word. Fields are assigned right-to-left on some machines, left-to-right on other machines; see §2.6. ‘An unnamed field is useful for padding to conform to externally.imposed layouts. AS a special case, an unnamed field with a width of 0 specifies alignment of the next field at a word boundary. Implementations are not required to support any but integer fields. Moreover, even int fields ‘may be considered to be unsigned. For these reasons, itis recommended that fields be declared as. ‘unsigned. The address-of operator & may not be applied to them, so that there are no pointers tw fields. Fields may not be union members. 8.5.14 Nested classes ‘Accass may be declared within another class. In tis case, the soope of the name of the inner class and its public names is restricted to the enclosing class. Except for this restriction the inner class could have been declared outside its enclosing class. Declaring a class within another does not affect the rules for access to private members, nor does it place the member functions of the inner class in the scope of the enclosing class. For example: int xi class enclose { int x: class inner ( g(innere); iy int inner; enclose.g(inners p) ( ... } In this example, the x in £ refers to the x declared before class enclose. Since y is a private member of inner, g can not use it. Since g is a member of enclose, names used in g are C C++ Reference Manual 28 resolved in the scope of class enclose. Therefore inner in the argument declaration for g refers to the enclosed type inner, and not to the int. 8.6 Initialization A declarator may specify an initial value for the identifier being declared. The initializer is preceded by =, and consists of an expression or a list of values nested in braces. initializer: ‘= expression = Cintlalizer-list > { inisializerslise } All the expressions in an initializer for a static or external variable must be constant expressions, which are described in $15, o expressions which reduce to the address of a previously declared variable, possibly offset by a constant expression. Automatic or register variables may be initialized by arbitrary expressions involving constants, previously declared variables and functions. Static and external variables which are not initialized are guaranteed to start off as 0; automatic and register variables which are not initialized are guaranteed to start off as garbage. ‘When an initializer applies to a scalar (a pointer or an object of arithmetic type), it consists of single expression, pethaps in braces. The initial value of the object is taken from the expression; the same conversions as for assignment are performed. Note that since () is not an initializer, **x a( 57" is not the declaration of an object of class x, but the declaration of a function taking no argument and renaming an x. 8.6.1 Initializer lists ‘When the declared variable is an aggregate (a class or an array) then the initializer may consist of 1a brace-enclosed, comma-separated list of intializers for the members of the aggregate, wnitten in increasing subscript or member ordet. If the array contains subaggregates, this rule applies recursively to the members of the aggregate. If there are fewer initilizers in the list than there are members of the aggregate, then the aggregate is padded with O's. Braces may be elided as follows. If the initializer begins with a left brace, then the succeeding ‘comma-separated list of initalizers initializes the members of the aggregate; it is erroneous for there to be more initializers than members. If, however, the initializer does not begin with a left ‘brace, then only enough elements from the list are taken to account for the members of the aggregate; any remaining members are left to initialize the next member of the aggregate of which the current aggregate is a part. For example, ant xl] (1, 3,55 declares and initializes x as a 1-dimensional array which has three members, since no size was specified and there are three initializers. (C++ Reference Manual 29 float y{4}(3] C3 (2, 4, 3,5, hy h is a completely-bracketed initialization: 1, 3, and 5 initialize the first row of the array y[0), namely y(0}{0}, y01[1], and yl0]{2]. Likewise the next rwo lines inialize y{1] and yl2J. The initializer ends early and therefore y{3} is initialized with 0. Precisely the same ‘effect could have been achieved by Float yf4)t3] = ¢ 1,3, 5, 2, 4, 6, 3, 5,7 hn ‘The initializer for y begins with a left brace, but that for y{01 does not, therefore three elements from the list are used. Likewise the next three are taken successively for y{ 1] and y{21. Also, Float yf4)[3) = { Cth C2 C3 COD h initializes the first column of y (regarded as a two-dimensional array) and leaves the rest 0. 8.6.2 Class objects ‘An object with private members cannot be initalized by simple assignment to its members as described above; neither can a union object. An object of a class with a constructor must be initialized. If a class has a constructor which does not take arguments that constructor is used for ‘objects which are not explicitly initialized, ‘The arguments for a constructor can also be presented as a parenthesized list; this style must be ‘used when creating objects on the free store. For example: struct complex { float re, in; complex(fioat r, complex(float z) Ms complex 22(1, 2.335 complexe zp = new complex(1, 2.3); alization can also be performed by explicit assignment; conversions are performed. For example, complex 221 = complex(1, 2-3); complex 222 = complex( 123); complex 223 = 123; complex 224 = 223; If a constructor taking a refereace to an object of its own class exists, it will be invoked when an object is initialized with another object of thet class, but not when an object is initialized with a constructor. ‘An object can be a member of an aggregate only if the object's class does not have a constructor or if one of its constructors takes no arguments. In the latter case that constructor is ealled when the aggregate is created, If a member of an aggregate is of a class with a destructor then that destructor is called when the aggregate is destroyed. an (C++ Reference Manual 30 8.6.3 References ‘When a variable is declared to be a 76, that is “reference to type 7”, it can be initialized either by ‘a pointer to type 7, or by an object of type 7. In the latter case the address-of operator & will be ‘implicitly applied. For example: ant 43 anth rt = 4; ant r2 © Bi; Both x1 and x2 will reference 4. IniNalization of a reference is treated very differently from assignment to it, As described in §7.1 a reference is implicitly dereferenced when used. For example rte 125 ‘means copy the integer referenced by r2 into the integer referenced by x1 A reference must be initialized. Because of the implicit dereferencing the value of a reference cannot be changed after initialization. A reference can therefore be thought of as a name of an object. ‘The expression Ax 1 yields the address of the object referenced by 1. Thus to get a pointer pp to denote the same chject as x1 one can write ppaBr. If the inkializer for a reference to type 7 is not an Ivalue an object of type 7 will be created and initialized with the initializer using the usual initialization rules. The address of that object then becomes the value of the reference. The lifetime of an object created in this way is the scope in which itis created. For example: Goubiek rr = 1; is legal and rx will point to a double containing the value 1.0, References are particularly useful as formal argument types. 8.6.4 Character arrays AA final abbreviation allows a char array to be initialized by a string, In this case successive characters of the string initialize the members of the array. For example, char msg{] © "Syntax error on line Xa\n"; shows a character array whose members are initialized with a string. 8.7 Type names Sometimes (to specify type conversions explicitly, and as an argument of sizeof or new) it is desired to supply the name of a data type. This is accomplished using a “type name,” which in essence is a declaration for an object of that type which omits the name of the object. ‘ype-name: ‘ype-specifier abswract-declaraior abstract-declarator: empry abstract-declorator abstract-declaraor ( argumentedeclaration-list ) absiract-declarair { consiant-exprestionsy, } (abseract-declarator ) {itis possible to identify uniquely the location in the abstract-deciarator where the identifier would appear if the construction were a declarator in a declaration. The named type is then the same as the type of the hypothetical identifier. For example, von C++ Reference Manual 31 int int « int «(31 int #0) ant (0 name respectively the types “integer,” “pointer to integer,” “pointer to an array of three {integers,” “function returning pointer to integer,” and “pointer to function returning an integer.”” 8.8 Typedef Declarations containing the deci-specifier typedef define identifiers which can be used later as if they were type keywords naming fundamental or derived types. ypedef-name: identifier Within the scope of a declaration involving typedef, each identifier appearing as part of any declarator therein becomes syntactically equivalent to the type keyword naming the type associated with the idemifier in the way described in §8.4. The name of a class or an enum is also a npedef- name. For example, after typedef int MILES, #KLICKS?; struct complex { double re, im; }; the constructions MILES distance; extern KLICKSP metricp; complex 2, #zp; are all legel declarations; the type of distance is int, that of metricp is “pointer to int”. typedef does not introduce brand new types, only synonyms for types which could be specified in another way. Thus in the example above éistance is considered to have exactly the same type as any other int object. A class declaration, however, does introduce a new type. For example: struct x { int ay}: struct ¥ { int aj 3; xat; declares three variables of three different types. ‘A declaration of the form name-declaration: ‘aggr identifier + enum identifier ; specifies that an identifier is the name of some (possibly not yet defined) class or enumeration, ‘Such declarations allows declaration of classes which refer to each other. For example: (C++ Reference Manual 32 ou vector; class matrix { friend matrix operators(matrixk, vectors); vector { friend matrix operators(matrixk, vectors); h 8.9 Overloaded function names ‘When several (different) function declarations are specified for a single name, that name is said to be overloaded. When that name is used, the correct function is selected by comparing the types of the actual arguments with the argument types in the function declarations. Of the usual arithmetic conversions defined in $6.6 only the conversions char->short> int, int- >double, int->long, and float->double are performed for a call of an overloaded function. To overload the name of a non-member function an overload declaration must precede any declaration of the function; see $8.2. For example, overload abs; int abs(int); double abs (double ‘When an overloaded name is called, the list of functions is scanned in order to find one which can be invoked. For example abs(12) will invoke abs(int) and abs(12.0) will invoke abs(double). Had the order of declarations been reversed, both calls would have invoked abs (double). 1, for a call of an overloaded name, no function is found by the method above, the set of user defined conversions (58.5.6) is examined. If there is a unique set of user-defined conversions which makes the call legal, it is implicitly applied. For example: class x (4. x(4nt); 35 clase ¥ ( ... (int); overioad int £(x), £(¥); overload int g(x), g(Z); £005 7» Adlegal: ambiguous £(x(1)) or £(¥(1)) «/ 9105 Ze (XC) ” g("asde"); — /# g(z("asdt")) ” ‘All operator function names are automatically overloaded. ‘The address-of operator & may only be applied to an overloaded name in an assignment or an initlalization where the type expected determines which function to take the address of. For exampl int operators (matrix6, matrixk); int operatore(vectors, vectork); int («pfm)(matrixh, matrixk) = Soperator: int (#pfv)(vectork, vectori) = Soperator: int («pfx)(...) = Koperators J» error #/ C++ Reference Manual 33 8.10 Enumeration declarations Enumerations are int types with named constants, enum-specifier: enum idensfier,y, { enum-list} enumelist , enumerator enumerator: identifier identifier = constant-expression ‘The identifiers in an enum-list are declared as constants, and may appear wherever constants are required. If no enumerators with = appear, then the values of the corresponding constants begin at O and increase by 1 as the declaration is read from left-to-right. An enumerator with = gives the associated identifier the value indicated; subsequent identifiers continue the progression from the assigned value. ‘The names of enumerators must be distinct from those of ordinary variables. The names of coumerators with different constants must also be distinct. The values ot the exumerators need not be distinct. ‘The role of the identifier in the enum-specifir is entirely analogous to that of the class name; it ‘names a particular enumeration. For example, burgundy, clarete20, winedark }; enum color { chartreus color scp, col; col = claret; ep * col; if (sep em burgundy) ... makes color the name of a type describing various colors, and then declares ep as a pointer to an object of that type, and co1 as an object of that type. The possible values are drawn from the set 40, 1, 20, 21}. 8.11 Asm declaration ‘An asm declaration has the form asa (sing ) 5 ‘The meaning of an asm declaration is not defined. Typically itis used to pass information through the compiler to an assembler. ). STATEMENTS Except as indicated, statements are executed in sequence. 9.1 Expression statement ‘Most statements are expression statements, which have the form expression 5 ‘Usually expression statements are assignments or function calls. C++ Reference Manual 34 9.2 Compound statement, or block So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provid compound-statement: { statements, > statement-list: statement Statement statement-list Note that a declaration is an example of a statement ($9.15). 9.3. Conditional statement ‘The two forms of the conditional statement are A ( expression ) statement Af ( expression ) statement ei ‘The expression must be of integral ot pointer type or of a class type for which # conversion to {integral or pointer type is defined (see §8.5,6). ‘The expression is evaluated and if it is non-zero, the first substatement is executed. If else is used the second substatement is executed if the expression is 0. As usual the “else” ambiguity is resolved by connecting an else with the last encountered else-less 4¢. 9.4 While statement ‘The while statement has the form while ( expression ) statement ‘The substatemen is executed repeatedly so long as the value of the expression remains non-zero. ‘The test takes place before each execution of the statement. The expression is handled as in a conditional statement ($9.3). 9.5 Do statement ‘The do statement has the form 0 statement while ( expression ) ; ‘The substatement is executed repeatedly until the value of the expression becomes zero. The test ‘takes place after each execution of the statement. The expression is handled as in a conditional statement (59.3). 9.6 For stitement ‘The for statement has the form for ( statement expression], 3 erestion-2,,, ) statement? This statement is equivalent to statement-1 while (expression!) { statement-2 expression-2 , ‘Thus the first statement specifies initialization for the loop; the first expression specifies a test, ‘made before each iteration, such that the loop is exited when the expression becomes 0; the second ‘expression often specifies an incrementing that is performed after each iteration. ( . C++ Reference Manual 35 Either or both of the expressions may be dropped. A missing expression-1 makes the implied whie clause equivalent to while( 1). Note that if siziement-1 is a declaration, the scope of the name declared extends to the end of the block enclosing the for-statement. 9.7 Switch statement ‘The switch statement causes control to be transferred to one of several statements depending on the Value of an expression. It has the form switch ( expression ) statement ‘The type of the expression must be of integral or pointer type. Any statement within the statement may be labeled with one or more case prefixes as follows: ease constantespression + ‘where the constant expression must be of the same type as the switch expression; the usual arithmetic conversions are performed. No two of the case constants in the same switch may have the same value. Constant expressions are defined in §15. ‘There may also be at most one statement prefix of the form default + ‘When the switch statement is executed, its expression is evaluated and compared with each case constant. If one of the case constants is equal to the value of the expression, control is passed to the statement following the matched case prefix. Hf no case constant matches the expression, and if there is a default prefix, control passes to the prefixed statement. If no case matches and if there is no default then none of the statements in the switch is executed. case and defasit prefixes in themselves do not alter the flow of comtrol, which continues ‘unimpeded across such prefixes. To exit from a switch, see break, $9.8. ‘Usually the statement that is the subject of a switch is compound. Declarations may appear at the ‘head of this statement, but initializations of automatic or register variables are ineffective. 9.8 Break statement ‘The statement break 5 causes termination of the smallest enclosing while, do, for, or switch statement; control passes to the statement following the terminated statement. 9.9 Contime statement ‘The statement continue ; causes control to pass to the loop-continuation portion of the smallest enclosing while, do, or for statement; that is to the end of the loop. More precisely, in each of the statements wnile (0) (dot for (444) ¢ contin: ; contin: y }while (...)5 8 continue is-equivalent to goto contin. (Following the contin: is a null statement, $9.13.) 9.10 Return statement ‘A function returns to its caller by means of the return statement, which has one of the forms ¢ C++ Reference Manual 36 return ; return expression ; ‘The first form can be used only in functions which does not return a value, that is, a function with the renum value type void. The second form can be used only in functions returning a value; the value of the expression is returned to the caller of the function. If required, the expression is converted, as in an initialization, to the type of the function in which it appears. Flowing off the end of a function is equivalent to a return with no returned value. 9.11 Goto statement ‘Control may be transferred unconditionally by means of the statement goto identifier : ‘The identifier must be a label (§9.12) located in the carrent function. It is not possible to transfer control past a declaration with an (implicit or explic) initializer. 9.12 Labeled statement ‘Any statement may be preceded by label prefizes of the form ldensifier + which serve to declare the identifier as a label. The only use of a label is as a target of a goto. ‘The scope of a label is the current function, excluding any sub-blocks in which the same identifier hhas been redeclared. See $4.1. 9.13 Null statement ‘The null statement has the form ‘A null statement is useful to carry a label just before the } of a compound statement or to supply a ‘mull body to a looping satement such as while. 9.14 Delete statement ‘The delete statement has the form delete expression 5 ‘The result of the expression must be a pointer. The object pointed to is deleted. That is, after the delete statement the object cannot be assured to have a well defined value; see $17. The effect of applying deiete to a pointer not obtained from the new operator (87.1) is undefined. However, deleting a pointer with the value zero is harmless. 9.15 Declaration statement ‘A declaration statement is used to introduce a new idemtifier into a block; it has the form declaration-natement: declararion If an identifier introduced by @ declaration were previously declared, the outer declaration is pushed down for the duration of the block, after which it resumes its force, Any initializations of auto or register variables are performed each time their declaration statement is executed. It is possible to transfer into a block, but not in a way that causes {nializations not to be performed; see $9.11. Initializations of variables with storage class static (84.2) are performed only once when the program begins execution, C++ Reference Manual 37 10. EXTERNAL DEFINITIONS ‘A program consists of a sequence of external definitions. ‘The scope of external definitions persists 10 the end of the file in which they are declared. The syntax of external definitions is the same as that of declarations, except that only at this level and within class declarations may the code for functions be given. 10.1 Function definitions Function definitions have the form function-definition: decl specifiers, functon-declarator base-class-intializer,function-body ‘The decl-sprcfiers register, auto, typedef may not be used, and friend, and virtual may conly be used within a class declaration (§8.5). A function declarator is similar to a declarator for a “function retuming ..."" except that it includes the names of the formal parameters of the function ‘being defined. Function declarators have the form Surction-declarator: declarator ( argumentdeclaration-lis ) The form of an argumen-declararion-list is specified in $84. If an argument is specified register, the corresponding actual parameter will be copied, if possible, into a register at the ‘outset of the function. Ifa constant expression is specified as initializer for an argument this value is used as a default argument value, ‘The function-body has the form Sunction-body: compound-statement A simple example of a complete function definition is ant max(int a, int b, int ¢) « int m= (a>b) Par by return (n> 0) ? mic; , Here int is the type-specifier; max(int a, int b, int ¢) is the fumctiondeclarator; { «. {s the block giving the code for the statement. ‘Since in expression context an array name (in particular as an actual parameter) is taken to mean a pointer to the first element of the array, declarations of formal parameters declared “array of..." are adjusted to read “pointer to ...". ‘A base class initializer has the form base-class-iniializer: C argumenttist, ) It is used to specify arguments for a base class constructor in a constructor for a derived class. For example: , struct base { ba struct derived : (int)i eee bs { derived(int); 66. 5 Gerived.derived(int a) : (at) (... } derived €( 1095 ‘The base class's constructor is called for the object ¢ with the argument 11. C++ Reference Manual 38 10.2 External data definitions ‘An external data definition has the form dora-defnition: declaration ‘The storage class of such data is static. XH there is more than one external data definition of the same name, the definitions must agree exactly in type and storage class and all initalizers (if any) must have the same value. 11. SCOPE RULES See 4.1. 12, COMPILER CONTROL LINES ‘The compiler contains a preprocessor capable of macro substitution, conditional compilation, and inclusion of named files. Lines beginning with # communicate with this preprocessor. These lines have syntax independent of the rest of the language; they may appear anywhere and have effect which lass (independent of scope) until the end of the source program file Note that const and inline definitions provide alternatives to most uses of #def ine. 12.1 Token replacement ‘A compiler-control line of the form #define identifier token-srring causes the preprocessor to replace subsequent instances of the identifier with the given string of tokens. Semicolons in, or at the end of, the token-string are part of that string. A line of the form #define identfier( identifier 5... , Identiter ) token-sring Where there is no space between the first identifier and the (, is a macro definition with fgemen.”Sobesuentintnces of the Sem iden followed ty a (a sequene of tokens delimited by commas, and a ) are replaced by the token string in the definition. Each occurrence of an identifier mentioned in the formal parameter list of the definition is replaced by the corresponding token string from the call. The actual arguments in the call are token strings separated by commas; however commas in quoted stings or protected by parentheses do not separate arguments. The number of formal and actual parameters must be the same. Strings and ‘character constants in the token-string are scanned for formal parameters, but strings and character constants in the rest of the program are not scanned for defined identifiers. Jn both forms the replacement string is rescanned for more defined identifiers. In both forms a long definition may be continued on another line by writing \ at the end of the line to be continued. A control line of the form fandef identifier causes the identifier’s preprocessor definition 19 be forgotten. 12.2 File inclusion ‘A compiler control line of the form include “filename” causes the replacement of that line by the entire contents of the file filename. The named file is searched for first in the directory of the original source file, and then in a sequence of specified or standard places. Alternatively, a control line of the form C+ Reference Manual 39 #include searches only the specified or standard places, and not the directory of the source file. (How the places are specified is not part of the language.) ‘#include’s may be nested. 12.3 Conditional compilation ‘A compiler control line of the form #4 expression checks whether the expression evaluates to non-zero, The expression must be @ constant expression as discussed in §15; the following additional restriction applies here: the constant expression may not contain sizeof or an enumeration constant.) In addition to the usual C++ operations a unary operator defined can be used. When applied to an identifier, its value is non- zero if that identifier has been defined using #4efine and not later undefined using #undef; otherwise its value is 0. A control line of the form #ita0t idenifier checks whether the identifier is currently defined in the preprocessor; that is, whether it has been the subject of a #detine control line. A control line of the form ifndef identifier checks whether the identifier is currently undefined in the preprocessor. ‘All three forms are followed by an arbitrary number of lines, possibly containing a contro! line fee and then by a control line endif If the checked condition is true then any lines berween #else and #endif are ignored. If the checked condition is fale then any lines between the test and an #elue or, lacking an #else, the endif, are ignored. ‘These constructions may be nested, 12.4 Line control For the benefit of other preprocessors which generate C++ programs, a line of the form line constant "filename" causes the compiler to believe, for purposes of error diagnostics, that the line number of the next source line is given by the constant and the current input file is named by the identifier. If the ‘identifier is absent the remembered file name does not change. 13. IMPLICIT DECLARATIONS See $8.1. 14, TYPES REVISITED ‘This section summarizes the operations which can be performed on objects of certain types. 14.1 Classes ‘Class objects may be assigned, passed as arguments to functions, and returned by functions (except objects of some derived classes; sce §8.5.3). Other plausible operators, such as equality comparison, can be defined by the user; see §8.5.10. (C++ Reference Manual 40 14.2, Functions ‘There are only two things that can be done with a function: calli, or take its address, If the name of a function appears in an expression not in the function-name position of a call, a pointer to the function is generated. Thus, to pass one function to another, one might say typedef int (#FF)(); extern g(PP); extern £05 (2); ‘Then the definition of g might read g(PF funep) t (sfunep) (); » Notice that £ must be declared explicitly in the calling routine since its appearance in g(#) was not followed by (. 14.3 Asrays, pointers, and subscripting Every time an identifier of array type appears in an expression, itis converted into a pointer to the first member of the array. Because of this conversion, arrays are not Ivalues. By definition, the subscript operator [] is interpreted in such a way that B1[E2) is identical to #((B1)+(E2)). ‘Because of the conversion rules which apply to +, if £1 is an array and £2 an integer, then B1(E2] refers to the Ba-th member of B1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation. A consistent rule is followed in the case of mult-dimensional arrays. If E is an n-dimensional array of rank 1x/x *- +X, then E appearing in an expression is converted to a pointer to an (n=1)-dimensional array with rank jx ++ xk. Ifthe « operator, either explicitly or implicitly as a result of subscrigting, is applied to this pointer, the result is the pointed-to (n—1)-dimensional array, which itself is immediately converted into a pointer. For example, consider ant «131515 Here x is a 3%5 array of integecs. When x appears in an expression, it is converted to a pointer to (the first of three) S-membered arrays of integers. In the expression x{ 1, which is equivalent to (xed), x is first converted to a pointer as described; then 4 is converted to the type of x, Which involves multiplying 4 by the length the object to which the pointer points, namely 5 integer objects. The results are added and indirection applied to yield an array (of 5 integers) which in tum is converted to a pointer to the first of the integers. If there is another subscript the same argument applies again; this time the result is an imeger. Ik follows from all this that arrays in C++ are stored row-wise (last subscript varies fastest) and that the first subscript in the declaration helps determine the amount of storage consumed by an array but plays no other part in subscript calculations. 14.4. Explicit pointer conversions Certain conversions involving pointers are permitted but have implementation-dependent aspects. ‘They are all specified by means of an explicit type-conversion operatot, §87.2 and 8. van C++ Reference Manual a ‘A pointer may be converted to any of the integral types large enough to hold it. Whether an int fot Long is required is machine dependent. The mapping function is also machine dependent, but is intended to be unsurprising to those who know the addressing structure of the machine. Details for some particular machines were given in §2.6. ‘An object of integral type may be explicitly converted to a pointer. The mapping always carries an integer converted from a pointer back to the same pointer, but is otherwise machine dependent. A pointer to one type may be converted to a pointer to another type. The resulting pointer may cause addressing exceptions upon use if the subject pointer does not refer to an object suitably aligned in storage. It is guaranteed that a pointer to an object of a given size may be converted 10 a pointer to an object of a smaller size and back again without change. Different machines may differ in the number of bits in pointers and in alignment requirements for objects. Aggregates are aligned on the strictest boundary required by any of their constituents. 15. CONSTANT EXPRESSIONS In several places C++ requires expressions which evaluate to a constant: as array bounds (58.3), as case expressions (§9.7), as default function arguments (§8.3), and in initializers (§8.6). In the frst case, the expression can involve only integer constants, character constants, enumeration constants, names declared const, and sizeof expressions, possibly connected by the binary operators bo LB Tt ce oe me te ce ce oe ek HT or by the unary operators Soo or by the ternary operator a Parentheses can be used for grouping, but not for function calls. ‘More latiude is permitted for the other three uses; besides constant expressions as discussed above, float constants are permitted, and one can also apply the unary & operstor to external or static objects, or to external or static arrays subscripted with a constant expression. ‘The unary & can also be applied implicitly by appearance of unsubscripted arrays and functions. ‘The basic rule {ig that initalizers must evaluate ether to a constant or to the address of a previously declared ‘external or static object plus or minus a constant. Less latimude is allowed for constant expressions after #if; names declared const, sizeof ‘expressions, and enumeration constants are not permitted. 16. PORTABILITY CONSIDERATIONS Certain parts of C++ are inherently machine dependent. The following list of potential trouble spots is not meant to be all-inclusive, but to point out the main anes. Purely hardware issues like word size and the properties of flosting point arithmetic and integer division have proven in practice to be not much of a problem. Other facets of the hardware are refected in differing implementations. Some of these, particularly sign extension (converting a negative character into a negative integer) and the order in which bytes are placed in a word, are a nuisance that must be carefully watched. Most of the others are only minor problems. ‘The number of register variables that can actually be placed in registers varies from machine to ‘machine, as does the set of valid types. Nonetheless, the compilers all do things properly for their ‘own machine; excess or invalid register declarations are ignored. ( C++ Reference Manual 2 Some difficulties arise only when dubious coding practices are used. It is exceedingly unwise to write programs that depend on any of these properties. ‘The order of evaluation of function arguments is not specified by the language. It is right-to-left on some machines left-to-right on others. The order in which side effects take place is also unspecified. Since character constants are really objects of type int, multi-character character constants may be ‘permitted. The specific implementation is very machine dependent, however, because the order in ‘which characters are assigned to a word varies from one machine to another. On some machines fields are assigned left-to-right in a word, in others right-to-left. ‘These differences are invisible to isolated programs which do not indulge in type punning (for example, by converting an int pointer to a char pointer and inspecting the pointed-to storage), but must be accounted for when conforming to externally-imposed storage layouts. 17, FREESTORE ‘The new operator (87.2) will call the function extern voids operator new(long); to obtain storage. The argument specifies the number of bytes required. The store will be uninitialized. If operator new() cannot find the amount of store required it will return zero. ‘The delete operator will call the function extern void operator delete(voide); 10 free the store pointed to for re-use. The effect of calling operator delete() for a pointer not obtained from operator new() is undefined, and so is the effect of calling operator delete() twice for the same pointer. However, deleting @ pointer with the value zero is harmless. Default versions of operator new() and operator delete() are provided, but a user may supply others more suitable for particular applications. ‘When a class object is created using the new operator the constructor will (implicitly) use operator new() to obtain the store needed. By assigning to the this pointer before any use of fa member a constructor can implement its own storage allocation. By assigning a zero value to this, a destructor can avoid the standard deallocation operation for objects of its class. For example: class cl { int vf10]; c1(0) { this = myownallocator( sizeof(el) ); } -e1() { my.owndeallocator( this }; this = 0; » (On entry into a constructor this is non-zero if allocation has already taken place (as is the case for auto objects) and zero otherwise, If a derived class assigns to this, the call to its base class's constructor (if any) will take place after the assignment so that the base class constructor will refer to the object allocated by the derived class's constructor. If a base class's constructor assigns to this, the new value will also be used by the derived class's constructor (if any). 18. SYNTAX SUMMAY This summary of C++ syntax is intended to be an aid to comprehension. It is not an exact statement of the language. ~~ C++ Reference Manual a 18.1 Experessions expression: ‘em expression binary-operator expression ‘pression? exprestion : exprestion expressionist verm: primary Stern item = term 1 term term seterm cliem termes term =~ Ciypename ) expression Sinplesypename ( exprestonlist) stzeot expression sizeof ( openane ) new ppe-name new ( ppename ) primary: 11 ddemtifier constant ring this expression primary expression | Primary ( expressionist, ) Primary « id Primary => id idenaifier ‘operator function-name pedef-name + : operator function-name expressionclist, expression nary-operator binary-operaior special-operator free-store-operaior Binary operators have precedence decreasing as indicated: C++ Reference Manual 7% ote ‘ t ivy it eee hee unary-operator: one of i special-operator: one of oo” free-sore-operaior: one of new delete ope-nane: declspectfiers absrac-declartor ‘abstract-declarator: emp ¢ abstract-declaraior abstract-declarator ( argument-declaration-list) abstracrdeclarator { constans-expression y, } simple-sype-name: pedef-name char mort ine dong unsigned float double void npedef-name: identifier 18.2 Declarations deciaration: dect-spectfiersy, declarator ist, § name-declaraston . asm-declaration Be tee C++ Reference Manual name-declaration: ‘ager identifier enum idenifier ; ager: class struct union ‘asm-declaration: Csering ) 5 declspecifiers: decl- specifier dec-specthirsg, declspecifir: ss-specifior ‘ppe-specifier ferspectier ‘friend typedet declaratorslist: initedeclarator initdeclarator , declarator-list Init declarator: declarator inalizer, declarator: dame ( declarator ) + const, declarator & const” declarator declararor™ argument-declaration-list ) eclarator { constantexprestiony, } “s C++ Reference Manual name. simple-dname pedef-name . simple-dname simple-dname: idensfier pedef-name = ppedefiname ‘operator function-name conversion-function-name ‘operator-function-name: ‘operator operator ‘conversion function-name: ‘operator ype argument-declaration-list: aredeclarationlist, «gp, rg-declaration-list: arg-declaration-list , argument-declaration ergumentdeclaration argument declaration: decl-specifiers declarator decl-specifiers declarator = constant-expression class-specifer: clastchead { member-list., > elasschead { member-lisor, public + memberlisiy, > class-head: 28a" ideniferp, Ber idenier, members member declaration memberlisoy 1 public,,, npedef-name ; smember-declaation: C decl-specifiers,, member-declaratorintialzer, funerion-definilon py = ‘member-declarator: declarazor identifier, * constant-espression intsializer: ‘= expression \ = Cinitializer-tst } = Cinitializer-tist 5 ( expression-list ) _ C++ Reference Manual 47 iniializer-list: expression initializer-list , iniializerslist { initalizer-list } enum-specifier: enum identfier,y, { enumclist } emumelist: ‘enumerator ‘enumlist , enumerator ‘enumerator: iderafier ‘identifier = constant-expression 18.3 Statements ‘compound-statement: { statementlistgy > statement-list: statement ‘Statement statement-list Statement: declaration expression ; 4 ( expression ) sarement 4 ( expression ) statement elae statement while ( expression ) statement o statement while ( expression ) + for ( statement expression,,, + expression, statement switch ( expression ) sidtement — ‘cane connan-espression : satement default : staement break continue return expression, 5 goto idenifier ; identifier: statement deiete expression ; 18.4 External definitions program: external-definision ‘external-definition program external-definision: function-definition ‘declaration Cy C++ Reference Manual 48 Sunetion-dfintion: decl-spectfiertg, ncton-declaraior bate-classintiliser, unction-body Sunction-declarator: declarator ( argument-declaration-list ) Sunetion-body: compoundestatement base-class-iniializer: + ( argumentlist,s, ) ‘opt 18.5 Preprocessor ‘#8ef ine identifier token-string #define identifier ( identifier , ... , identifier ) token-sring #48 expression #itdet identifier #itndef identifier #include * filename * #inelude < filename > #Line consiant" filename * undef idenifier 19, DIFFERENCES FROM C 19.1 Extensions ‘The types of function arguments can be specified (§8.4) and will be checked (87.1). Type ‘conversions will be performed (87.1). Single-precision floating arithmetic may be used for oat expressions; §6.2. Function names can be overloaded; $8.6. Operators can be overloaded; §7.16, $8.5.10. Functions can be inline substituted; $8.1. ‘Data objects ean be const; §8.3. Objects of reference type can be declared; $8.3, $8.6.3. A fire store is provided by the new and delete operators; §17. asses can provide data hiding (§8.5.8), guaranteed initialization (§8.6.2), user-defined conversions ($8.5.6), and dynamic typing through use of virtual functions (§8.5.4). ‘The name of a class is a type name; $8.5. ‘Any pointer can be assigned to a voids without use of a cast; §7.14. A declaration within a block is a statement; §9.15. ‘Anonomous unions can be declared; §8.5.12. 19.2 Summary of incompatibilities Mont consrocs in C ave legal n C++ with thir meaing mctimged, The exepions ae es lows C++ Reference Manual 49 Programs using one of the new keywords class const delete = friend inline new operator overload public this virtual as identifiers are not legal. ‘The function declaration £05 ‘means that ¢ takes no arguments, in C it means that £ could take arguments of any type at all. ‘The default scope of a name declared outside any block or class is fle; in C it was program. This {implies that to make a name visible to functions in other files a name must explicitly be declared extern; thus ant ay £0 0 in C++ is static int a; static £0 ( in C, and extern int aj int a; extern £() () inC++ is int as £0 O in C. However, note that int £05 means extern int £(); in both C++ and C. ‘Since class names in C++ are in the same name space as other names, constructs like struct # { int struct stat sta ‘cannot be used. 19.3 Anachronisms A class name can be prefixed with the one of the keywords class, struct, or union in the declaration of class objects, pointers, etc. For example struct & struct # £() ‘Programs using the old function definition syntax de 4 *Pi C++ Reference Manual 50 old-function-declarator: declarator ( parameter-list ) parameter-list: identifier identifier. identifier for example max(a,b) { return (acb) 7b: a; } may be used. If a function defined like this has not been previously declared its argument type will be taken to be (...), that is, unchecked. If it has been declared its type must agree with that of the declaration. ber sya conversion, pointer ineger 5,10, 41 5 oubie ype 16 ‘ouble-fuoat conversion S ‘lipas 17 alee 39 empty statement 36 fenaie 39 Sa Gelman 5 ‘enumeration consanes 33 ccxample of default amen: 19 ccxample of derived cass 22 txample of enumeration 33 example of friend funcons 28 fxumple of function declaration 19 ‘cumple of pede 3 ‘example of use of elias 19 fiend cass 26 fiend Anions 25 ‘Eesand specifier, $ fiend, virea end 23 fiend Ameen, intine 26 geiend functions, example of 25 ( operntor, 27 operator, datined 39 ‘opera, delete 2 Et 7 ‘ sae Ste a a fier eatse. 14 FS: ange cam 16 ‘ait, nye 18 Spetbe, viewed 15 Py aaanen 2 ‘rene, sequncng of 33 Ricte dass mente 20 ‘sorage diss, meomatic 4 ‘Borage dass decaration 14 smorage ss specifier 14 ore cas Spee, ming 15 subscripting, array explanation of 40 fubeeripeing, example of 19 subseripting operator 26 or, overloaded 14 ae int a iit EE i fi resicions on 18, cexpresion 8 ait & i i ot ‘pion, clase struct 20 union constructors 26 union, field 27 ‘sien nanber functions 26 unions 4, 26 queens, type conversion 32 , umer=dezined type-convarsion unkrows function aryunent types 17 the el clipas example of 19 ‘Scstetoed ype coer fom 3 20 Appendix jun Time Errors When an error is detected at run time, task_error() is called. This function will examine error_fet, and if this variable denotes a function, that function will be called with the error number and this as arguments, otherwise the error number will be given as argument to print_error{) which will print an error message on stderr and terminate the program. (xomorm) (zazsoas) Ixoezsto] (ErasKMODE) (ETASRDEL} UEDRASKPRE] (zormmapEL} (elscunzHe) (zscuoay1 [eLopEL} (rcevocerpnz) txstack) tx_stoxr} (elaesunt) [elwart) Attempt to delete object which renenbera a task. Attempt to delete an object which de still on sone chain. Attempt to put toa full queue. ‘Attexpt to put an object already on some queue. Attenpt to putback an object already on sone quent Attempt to putback to a full queue, ‘Attexpt to get from an enpty queua. Clock was non-zero when setclock() wan called. ‘Avtenpt to resune TERMINATED task. ‘Attenpt to resune ROWING task. Megetive argunent to delay(). ‘Attenpt to resume task or tiner already on sone queue, Bad arguments for histogran.new(). Bad mode for task-new(). Attempt to delete non-TERNINATED task. ‘Actempt to preempt a non-RUNNING task, Attempt to delete a non-TERMIMATED tis Scheduler chain corrupted: bad tin ‘Task ron time stack overflow. Mo more free store - MEW failed. ‘A task attenpted to obtain its om resuit(). ‘A task attempted to wait() for itself to TERMINATE. 2 21 Appendix C: A Program using Tasks include /+ trivial test example: ake a set of tasks which pass an object round between thenselves ‘uae printf to indicate progress WARNING: this program sets up an infinite loop ” class pe : public task ( pe(chare, qtails, gh 005 h void pe.pe(chare n, qtatle t, gheade h) :(1,0,0) 4 printe(*new po(Xa,%@,48)\n" n,,) white (1) { objects p = h-pgeti)s printé ("tak Xe\n",n); teoput(p) nain() heads bh © new qhead; qtaile t = bhestatl(); heads hs print (‘nain\n" for (int tm0; 4<20; +e) { chaze n= nev char[2]; /« make a one letter task nane +/ nf] = ‘aredy alt] = 05 hs new qhes ew pe(nyt)h)} prince (taain() f= hestadl( 8 Loop\n") ? new pe("ftzet po" styhh); printé(*nain: here we go\n"); E->put (new object); printf ("main exit\n")

You might also like