home *** CD-ROM | disk | FTP | other *** search
-
- ΓòÉΓòÉΓòÉ 1. How to Use the VisualAge for C++ Language Reference ΓòÉΓòÉΓòÉ
-
- The VisualAge for C++ Language Reference is a language reference guide for C
- and C++ programmers. It provides information about the VisualAge for C++
- implementation of both the C and C++ languages, including code examples, to
- enable you to write C and C++ programs.
-
- This document is a reference rather than a tutorial. It assumes you are already
- familiar with C and C++ programming concepts.
-
- With the exception of the separate introductory sections for each language and
- the additional C++-specific topics (such as templates and exception handling),
- information applies to both the C and C++ languages. Differences between the
- two languages in the implementation of a construct or concept are indicated.
-
- Before you begin to use this information, it would be helpful to understand how
- to navigate through it. You can use the Table of Contents and Index facility to
- locate topics and the Search facility to search the text of this document. You
- can use hypertext links to acquire related information on the current topic.
- Hypertext links appear in a different color. For example, here is a link to
- another panel: Communicating Your Comments to IBM. By double-clicking on the
- text of the link or by pressing Enter on a highlighted link, you will open a
- panel of related information. When you open a panel, the first link has the
- focus; to shift the focus to other links, use the Tab key.
-
- You should also understand:
-
- How to Use the Contents
- How to Get More Information on a Topic
- How to Use Menu Bar Choices
- How to Cut and Paste Examples
-
-
- ΓòÉΓòÉΓòÉ 1.1. How to Use the Contents ΓòÉΓòÉΓòÉ
-
- When the Contents window first appears, some topics have a plus (+) sign beside
- them. The plus sign indicates that additional topics are available.
-
- To expand the Contents if you are using a mouse, click on the plus sign. If you
- are using the keyboard, use the Up or Down Arrow key to highlight the topic,
- and press the plus (+) key. For example, Preprocessor Directives has a plus
- sign beside it. To see additional topics for that heading, click on the plus
- sign or highlight that topic and press the plus (+) key.
-
- To view a topic, double-click on the topic (or press the Up or Down Arrow key
- to highlight the topic, and then press the Enter key).
-
-
- ΓòÉΓòÉΓòÉ 1.2. How to Get More Information on a Topic ΓòÉΓòÉΓòÉ
-
- After you select a topic, the information for that topic appears in a window.
- Highlighted words or phrases indicate that additional information is available.
- Words and phrases highlighted in a different color from the surrounding text
- are called hypertext terms.
-
- If you are using a mouse, double-click on the highlighted word. If you are
- using a keyboard, press the Tab key to move to the highlighted word, and then
- press the Enter key. Additional information then appears in a window.
-
-
- ΓòÉΓòÉΓòÉ 1.3. How to Use Menu Bar Choices ΓòÉΓòÉΓòÉ
-
- Several choices are available for managing information presented in this
- document. There are three choices on the menu bar: the Services menu, the
- Options menu, and the Help menu.
-
- Use the Services menu to operate the active window currently displayed on the
- screen. Available actions include the following:
-
- Bookmark
- You can set a placeholder so you can retrieve information of interest to
- you.
-
- Search
- You can find occurrences of a word or phrase in the current topic, selected
- topics, or all topics.
-
- Print
- You can print one or more topics. You can also print a set of topics by
- first marking the topics in the Contents list.
-
- Copy
- You can copy a topic that you are viewing to the System Clipboard or to a
- file that you can edit. This method is particularly useful for copying
- syntax definitions and program samples into the application that you are
- developing.
-
- Select actions from the Options menu, to change the way your Contents list is
- displayed. To expand the Contents and show all levels for all topics, choose
- Expand all from the Options pull-down. You can also press the Ctrl, Shift, and
- * keys together.
-
- You can select various types of help information from the Help menu.
-
- For information about any of the menu choices, highlight the choice in the
- menu and press F1.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Placing Bookmarks ΓòÉΓòÉΓòÉ
-
- When you place a bookmark on a topic, it is added to a list of bookmarks you
- have previously set. You can view the list, and you can remove one or all
- bookmarks from the list. If you have not set any bookmarks, the list is empty.
-
- To set a bookmark, do the following:
-
- 1. Select a topic from the Contents.
- 2. When that topic appears, select the Bookmark option from the Services
- menu.
- 3. If you want to change the name used for the bookmark, type the new name
- in the field.
- 4. Click on the Place radio button (or press the Up or Down Arrow key to
- select it).
- 5. Click on OK (or select it and press Enter). The bookmark is then added to
- the bookmark list.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Searching for Information ΓòÉΓòÉΓòÉ
-
- You can specify a word or phrase to be searched. You can also limit the search
- to a set of topics by first marking the topics in the Contents list.
-
- To search for a word or phrase in all topics, do the following:
-
- 1. Select the Search option from the Services menu.
- 2. Type the word or words to be searched for.
- 3. Click on All sections (or press the Up or Down Arrow keys to select it).
- 4. Click on Search (or select it and press Enter) to begin the search.
- 5. The list of topics where the word or phrase appears is displayed.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Printing Information ΓòÉΓòÉΓòÉ
-
- You can print one or more topics, the index, or the table of contents. Make
- sure that your printer is connected to the serial port, configured correctly,
- and ready for input. To print:
-
- 1. Select Print from the Services pull-down.
- 2. Select what you want to print. Note that the This section and Marked
- sections choices are only available if you are viewing a topic or if you
- have marked topics, respectively. To mark topics in the table of
- contents, press the Ctrl key and click on the topics, or use the arrow
- keys.
- 3. Select Print to print what you've chosen on your printer.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Copying Information to a File ΓòÉΓòÉΓòÉ
-
- You can copy a topic that you are viewing in two ways:
-
- Copy copies the topic that you are viewing into the System Clipboard.
-
- Copy to file copies the topic that you are viewing into a temporary file
- named text.tmp. You can later edit that file by using any editor.
- text.tmp is placed in the directory where your viewable document resides.
- This copy function does not apply if you are viewing the document from
- the CD-ROM.
-
- To copy a topic, do the following:
-
- 1. Expand the Contents list and select a topic.
- 2. When the topic appears, select Copy to file from the Services menu.
- 3. The system puts the text pertaining to that topic into the temporary file
- text.tmp.
-
-
- ΓòÉΓòÉΓòÉ 1.4. How to Cut and Paste Examples ΓòÉΓòÉΓòÉ
-
- You can copy examples (or information) from this document to compile, link, and
- run them, or to paste them into your own code.
-
- To copy an example or information:
-
- 1. Make the topic you want to copy the active window.
-
- 2. From the Services menu, select Copy to file. The text in that topic is
- placed in the temporary file text.tmp, in the same directory as this
- reference. This copy function does not apply if you are viewing the
- document from the CD-ROM.
-
- 3. You can then modify or use text.tmp as you want.
-
- Note: Because the system copies the entire contents of the topic to the file,
- you may need to edit it to remove additional text. Most examples in this
- reference are ready to compile, link, and run as they appear, and do not
- require any editing.
-
-
- ΓòÉΓòÉΓòÉ 1.5. Other Information You Might Find Helpful ΓòÉΓòÉΓòÉ
-
- This product provides a number of online guides and references that we hope
- you'll find helpful as you develop applications. This information includes
- User's Guides, References, and How Do I help that gives you specific
- instructions for performing common tasks. You can get to this online
- information from the Information folder inside the main product folder. You can
- also get to it from the Help menu in any of the components of the product.
-
-
- ΓòÉΓòÉΓòÉ 1.6. Communicating Your Comments to IBM ΓòÉΓòÉΓòÉ
-
- If there is something you like, or dislike, about this book, please let us
- know. You can use one of the methods listed below to send your comments to IBM.
- Please be sure to include the complete title of the publication that you are
- commenting on.
-
- The comments you send should only pertain to the information in this document
- and its presentation. To request additional publications or to ask questions or
- make comments about the functions of IBM products or systems, you should talk
- to your IBM representative or your authorized IBM remarketer.
-
- When you send comments to IBM, you grant IBM a nonexclusive right to use or
- distribute your comments in any way it believes appropriate without incurring
- any obligation to you.
-
- You can send your comments to IBM in the following ways:
-
- By mail to the following address:
-
- IBM Canada Ltd. Laboratory
- Information Development
- 2G/345/1150/TOR
- 1150 EGLINTON AVENUE EAST
- NORTH YORK, ONTARIO
- CANADA M3C 1H7
-
- By FAX to the following number:
-
- - United States and Canada: (416) 448-6161
- - Other countries (+1) 416-448-6161
-
- By electronic mail to one of the following IDs. Be sure to include your
- entire network address if you wish to get a reply.
-
- - Internet: torrcf@vnet.ibm.com
- - IBMLink: toribm(torrcf)
- - IBM/PROFS: torolab4(torrcf)
- - IBMMAIL: ibmmail(caibmwt9)
-
-
- ΓòÉΓòÉΓòÉ <hidden> Related Information ΓòÉΓòÉΓòÉ
-
- Copyright
- Edition Notice
- Notices
- Trademarks and Service Marks
-
-
- ΓòÉΓòÉΓòÉ 1.7. Copyright ΓòÉΓòÉΓòÉ
-
- Copyright International Business Machines Corporation, 1996. All rights
- reserved.
-
- Note to U.S. Government Users - Documentation related to restricted rights -
- Use, duplication, or disclosure is subject to restrictions set forth in GSA ADP
- Schedule Contract with IBM Corp.
-
-
- ΓòÉΓòÉΓòÉ 1.8. Edition Notice ΓòÉΓòÉΓòÉ
-
- First Edition (February 1996)
-
- This edition applies to Version 3.5 of IBM VisualAge for C++ for Windows
- (33H4979, 33H4980) and to all subsequent releases and modifications until
- otherwise indicated in new editions. Make sure you are using the correct
- edition for the level of the product.
-
- This publication could include technical inaccuracies or typographical errors.
- Changes are periodically made to the information herein; any such changes will
- be reported in subsequent revisions.
-
- Requests for publications and for technical information about IBM products
- should be made to your IBM Authorized Dealer or your IBM Marketing
- Representative.
-
- When you send information to IBM, you grant IBM a nonexclusive right to use or
- distribute the information in any ways it believes appropriate without
- incurring any obligation to you.
-
-
- ΓòÉΓòÉΓòÉ 1.9. Notices ΓòÉΓòÉΓòÉ
-
- Any reference to an IBM licensed program in this publication is not intended to
- state or imply that only IBM's licensed program may be used. Any functionally
- equivalent product, program, or service that does not infringe any of IBM's
- intellectual property rights may be used instead of the IBM product, program,
- or service. Evaluation and verification of operation in conjunction with other
- products, except those expressly designated by IBM, is the user's
- responsibility.
-
- IBM may have patents or pending patent applications covering subject matter in
- this document. The furnishing of this document does not give you any license to
- these patents. You can send license inquiries, in writing, to the
-
- IBM Director of Licensing,
- IBM Corporation,
- 500 Columbus Avenue,
- Thornwood, NY, 10594,
- USA.
-
- Licensees of this program who wish to have information about it for the purpose
- of enabling: (i) the exchange of information between independent created
- programs and other programs (including this one) and (ii) the mutual use of the
- information which has been exchanged, should contact IBM Canada Ltd.,
- Department 071, 1150 Eglinton Avenue East, North York, Ontario M3C 1H7, Canada.
- Such information may be available, subject to appropriate terms and conditions,
- including in some cases payment of a fee.
-
- This publication contains examples of data and reports used in daily business
- operations. To illustrate them as completely as possible, the examples include
- the names of individuals, companies, brands, and products. All of these names
- are fictitious and any similarity to the names and addresses used by an actual
- business enterprise is entirely coincidental.
-
-
- ΓòÉΓòÉΓòÉ 1.10. Trademarks and Service Marks ΓòÉΓòÉΓòÉ
-
- The following terms used in this publication are trademarks or service marks of
- IBM Corporation in the United States or other countries:
-
- IBM
- IBMLink
- Personal System/2
- PS/2
- VisualAge
- WorkFrame
-
- Windows is a trademark of Microsoft Corporation.
-
- Other company, product, and service names, which may be denoted by a double
- asterisk(**), may be trademarks or service marks of others.
-
- IBM's VisualAge products and services are not associated with or sponsored by
- Visual Edge Software, Ltd..
-
-
- ΓòÉΓòÉΓòÉ <hidden> signed/unsigned types ΓòÉΓòÉΓòÉ
-
- The signed and unsigned types can be used with either a character (char) or an
- integer (int, short, long). The unsigned prefix indicates that the value of the
- object is to be a nonnegative value.
-
- For more information on conversions between signed and unsigned types, see
- Implicit Type Conversions.
-
-
- ΓòÉΓòÉΓòÉ <hidden> \ Character ΓòÉΓòÉΓòÉ
-
- The backslash can appear in string literals or comments as a punctuator. A
- backslash followed by a single character in C code indicates an escape
- sequence. A backslash by itself at the end of a line of C code is a
- continuation character.
-
- Escape Sequences provides help on escape sequences and the continuation
- character.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ( ) ΓòÉΓòÉΓòÉ
-
- Parentheses are used to group expressions to force a particular order of
- evaluation. A parenthesized expression usually contains one or more operators
- and operands (variables or constants), and is often part of an assignment
- expression. For example, ((x + y) * g) is a parenthesized expression.
-
- Parentheses are also used in function calls to group the argument list for the
- function. The opening parenthesis appears directly after the function name, and
- may be followed by any number of arguments (or no arguments), followed by the
- closing parenthesis and a semicolon. For example, fgets(line, 100, stream); is
- a function call.
-
- For help on parenthesized expressions, see Parenthesized Expressions ( ).
-
- For help on function calls, see Function Calls ( ).
-
-
- ΓòÉΓòÉΓòÉ <hidden> + ΓòÉΓòÉΓòÉ
-
- The plus (+) sign can be used as a unary operator to maintain the value of an
- operand, for example, +quality. The unary plus sign is the opposite of the
- unary minus (-) sign, which negates the value of an operand, for example,
- -quality.
-
- The plus sign can also be used as a binary operator in an arithmetic expression
- to represent the addition operation. For example, x + y indicates that the
- variables x and y are to be added together.
-
- For more information on the unary plus operator, see Unary Plus +.
-
- For more information on the addition operator, see Addition +.
-
-
- ΓòÉΓòÉΓòÉ <hidden> - ΓòÉΓòÉΓòÉ
-
- The minus (-) sign can be used as a unary operator to negate the value of an
- operand, for example -quality.
-
- It can also be used as a binary operator in an arithmetic expression to
- represent the subtraction operation. For example, x - y indicates that the
- variable y is to be subtracted from the variable x.
-
- For more information on the unary minus operator, see Unary Minus -.
-
- For more information on the subtraction operator, see Subtraction -.
-
-
- ΓòÉΓòÉΓòÉ <hidden> & ΓòÉΓòÉΓòÉ
-
- The ampersand (&) sign can be used as a unary operator to indicate the address
- of its operand. For example, &anyvar represents the address of the variable
- anyvar.
-
- The ampersand can also be used as a binary operator to represent the bitwise
- AND operation. For example, in the expression x & y, the corresponding bits of
- the x and y values are compared to see if the bits are both 1.
-
- A double ampersand (&&) is the logical AND operator. which indicate For
- example, in the expression x && y, the values of x and y are checked to see if
- both are nonzero values.
-
- For more information on the address operator, see Address &.
-
- For more information on the bitwise AND operator, see Bitwise AND &.
-
- For more information on the logical AND operator, see Logical AND &&.
-
-
- ΓòÉΓòÉΓòÉ <hidden> * ΓòÉΓòÉΓòÉ
-
- The asterisk (*) can be used as a unary operator to indicate indirection. For
- example, int *anyvar; declares anyvar as a pointer to int, that points to the
- value of *anyvar.
-
- The asterisk can also be used as a binary operator in an arithmetic expression
- to represent the multiplication operation. For example, x * y indicates that
- the variable x is to be multiplied by y.
-
- For more information on the indirection operator, see Indirection *.
-
- For more information on the multiplication operator, see Multiplication *.
-
-
- ΓòÉΓòÉΓòÉ <hidden> % ΓòÉΓòÉΓòÉ
-
- The percent (%) sign can be used simply to indicate percentage in a string
- literal. For example, "More than 50% agree".
-
- The percent sign is also used as part of the format specifier for the printf
- and scanf functions. For example, in the statement printf("The value is %d",
- anyint); the integer value of anyint is printed in the place of the %d
- specifier.
-
- The percent sign can also be used as a binary operator to represent the modulus
- (or remainder) operation. For example, the expression x % y indicates that x is
- divided by y, and the result of the expression is the remainder of the
- division.
-
- For more information on string literals, see String Literals.
-
- For more information on format specifiers, see the printf function or the scanf
- function in the IBM VisualAge for C++ for Windows C Library Reference.
-
- For more information on the remainder operator, see Remainder %.
-
-
- ΓòÉΓòÉΓòÉ <hidden> : ΓòÉΓòÉΓòÉ
-
- The colon (:) is used to indicate the end of a label and separate it from the
- following statement. For example, in the expression anylabl: x = y;, anylabl is
- a label that could be part of a switch statement or the target of a goto
- statement.
-
- The colon is also used in bit-field declarations to separate the identifier of
- the bit field and the storage it is given. For example, in the structure
-
- struct {
- unsigned x : 4
- unsigned y : 1
- }
-
- the bit fields x and y are assigned 4 bits and 1 bit of storage, respectively.
-
- The colon can also be used as part of the compound conditional expression (?:)
- to separate the two action expressions. For example, in the expression x = (y <
- z) ? y : z;, if y is less than z, the value of y is assigned to x; if y is not
- less than z, the value of z is assigned to x.
-
- For more information on labels, see Labels.
-
- For more information on bit fields, see the section Declaring and Using Bit
- Fields under Structures.
-
- For more information on the compound conditional expression, see Conditional
- Expressions.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ? ΓòÉΓòÉΓòÉ
-
- The question mark (?) is used for both trigraphs (three characters starting
- with ??) and as the first part of the operator for the conditional expression.
-
- For more information on the compound conditional expression, see Conditional
- Expressions.
-
-
- ΓòÉΓòÉΓòÉ <hidden> , ΓòÉΓòÉΓòÉ
-
- The comma (,) can be used to separate items such as parameters in a function
- call.
-
- The comma is also used in the comma expression to separate two operands. For
- example, in the expression x = (y++, z * 4);, the left operand is evaluated
- then discarded, and the value of the right operand is assigned to x.
-
- For more information on the comma expression, see Comma Expression ,.
-
-
- ΓòÉΓòÉΓòÉ <hidden> ; ΓòÉΓòÉΓòÉ
-
- The semicolon (;) is used to indicate the end of a C expression, for example,
- int x = 4;.
-
- The semicolon can also be used by itself as a null statement to show a
- nonexistent action.
-
- For more information on expressions, see Expression.
-
- For more information on null statements, see Null Statement.
-
-
- ΓòÉΓòÉΓòÉ <hidden> # ΓòÉΓòÉΓòÉ
-
- The number sign (#) is used to begin preprocessor directives. The # token must
- appear as the first character that is not white space on a line. The # is not
- part of the directive name and can be separated from the name with white
- spaces.
-
- It can also be used by itself as a null preprocessing directive The null
- directive performs no action. It consists of a single # on a line of its own.
-
- The null directive should not be confused with the # operator, which converts a
- parameter of a function-like macro into a character string literal.
-
- For more information on the # preprocessor operator, see # Operator.
-
- For more information on the null directive, see Null Directive (#).
-
- For more information on preprocessor directives, see Preprocessor Directive
- Format.
-
-
- ΓòÉΓòÉΓòÉ 2. Introduction to C and C++ ΓòÉΓòÉΓòÉ
-
- This chapter describes the C and C++ programming languages implemented by
- VisualAge for C++ and shows you how to structure C and C++ source programs. It
- also briefly summarizes the differences between C and C++, and discusses the
- principles of object-oriented programming.
-
- Refer to the IBM VisualAge for C++ for Windows Programming Guide for
- information about implementation-defined behavior in the VisualAge for C++
- environment.
-
- This section discusses:
-
- Overview of the C Language
- C Source Programs
- C Source Files
- Program Execution
- Scope in C
- Program Linkage
- Storage Duration
- Name Spaces
-
- Related Information
-
- Overview of the C++ Language
-
-
- ΓòÉΓòÉΓòÉ 2.1. Overview of the C Language ΓòÉΓòÉΓòÉ
-
- C is a programming language designed for a wide variety of programming tasks.
- It is used for system-level code, text processing, graphics, and in many other
- application areas.
-
- The C language described here is consistent with the Systems Application
- Architecture Common Programming Interface (also known as the SAA C Level 2
- interface), and with the International Standard C (ANSI/ISO-IEC
- 9899-1990[1992]). This standard has officially replaced American National
- Standard for Information Systems-Programming Language C (X3.159-1989)
- (X3.159-1989) and is technically equivalent to the ANSI** C standard.
-
- VisualAge for C++ supports most, but not all, of the changes adopted into the C
- Standard by ISO/IEC 9899:1990/Amendment 1:1994.
-
- C supports several data types, including characters, integers, floating-point
- numbers and pointers - each in a variety of forms. In addition, C also supports
- arrays, structures (records), unions, and enumerations.
-
- The C language contains a concise set of statements, with functionality added
- through its library. This division enables C to be both flexible and efficient.
- An additional benefit is that the language is highly consistent across
- different systems.
-
- The C library contains functions for input and output, mathematics, exception
- handling, string and character manipulation, dynamic memory management, as well
- as date and time manipulation. Use of this library helps to maintain program
- portability, because the underlying implementation details for the various
- operations need not concern the programmer.
-
- The IBM VisualAge for C++ for Windows C Library Reference describes all of the
- C library functions supported by the VisualAge for C++ compiler.
-
- Related Information
-
- Lexical Elements of C and C++
- Functions
- Type Specifiers
- Overview of the C++ Language
-
-
- ΓòÉΓòÉΓòÉ 2.2. C Source Programs ΓòÉΓòÉΓòÉ
-
- A C source program is a collection of one or more directives, declarations, and
- statements contained in one or more source files. The resulting collection of
- files constitutes a compilation unit.
-
- Statements Specify the action to be performed.
-
- Directives Instruct the preprocessor to act on the text of the program.
- Pragma directives affect compiler behavior.
-
- Declarations Establish names and define characteristics such as scope, data
- type and linkage.
-
- Definitions Are declarations that allocate storage for data objects or
- define a body for functions. An object definition allocates
- storage and may optionally initialize the object.
-
- A function declaration precedes the function body. The function body is a
- compound statement that can contain declarations and statements that define
- what the function does. The function declaration declares the function name,
- its parameters, and the data type of the value it returns.
-
- A program must contain one, and only one, function called main. The main
- function is the first function called when a program is run.
-
- C++ Note: This is not the case for C++ programs. If a C++ program
- instantiates an object in file scope, the constructor for that object is
- executed first.
-
- By convention, main is the starting point for running a program. It typically
- calls other functions. A program usually stops running at
-
- the end of the main function
- a return statement in the main function
- an exit function call.
-
- Source for a Simple C Program
-
- Related Information
-
- C Source Files
- Overview of the C Language
- C++ Programs
-
-
- ΓòÉΓòÉΓòÉ <hidden> Source for a Simple C Program ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- This is the source code of a simple C program:
-
- *
- ************************************************************************/
-
- /**
- ** This is an example of a simple C program
- **/
- #include <stdio.h> /* standard I/O library header that
- contains macros and function declarations
- such as printf used below */
-
- #include <math.h> /* standard math library header that
- contains macros and function declarations
- such as cos used below */
-
- #define NUM 46.0 /* Preprocessor directive */
-
- double x = 45.0; /* External variable definitions */
-
- double y = NUM;
-
-
- int main(void) /* Function definition
- for main function */
- {
- double z; /* Local variable definitions */
- double w;
-
- z = cos(x); /* cos is declared in math.h as
- double cos(double arg) */
- w = cos(y);
- printf ("cosine of x is %f\n", z); /* Print cosine of x */
- printf ("cosine of y is %f\n", w); /* Print cosine of y */
-
- return 0;
- }
-
- /************************************************************************
- *
-
- This source program defines main and declares a reference to the functions cos
- and printf. The program defines the global variables x and y, initializes them,
- and declares two local variables z and w.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 2.3. C Source Files ΓòÉΓòÉΓòÉ
-
- A C source file is a text file that contains all or part of a C source program.
- It can include any of the functions that the program needs. To create an
- executable module, you compile the separate source files individually and then
- link them as one program. With the #include directive, you can combine source
- files into larger source files. The resulting collection of files constitutes a
- compilation unit.
-
- A source file contains any combination of directives, declarations, and
- definitions. You can split items such as function definitions and large data
- structures between source files, but you cannot split them between compiled
- files. Before the source file is compiled, the preprocessor alters the source
- file in a predictable way. The preprocessor directives determine what changes
- are made to the source text. As a result of the preprocessing stage,
- preprocessor directives are completed, macros are expanded, and a source file
- is created containing C statements, completed directives, declarations, and
- definitions.
-
- It is sometimes useful to gather variable definitions into one source file and
- declare references to those variables in any source files that use them. This
- procedure makes definitions easy to find and change, if necessary. You can also
- organize constants and macros into separate files and include them into source
- files as required.
-
- Directives in a source file apply to that source file and its included files
- only. Each directive applies only to the part of the file following the
- directive.
-
- Example of C Source Files
-
- Related Information
-
- C Source Programs
- Overview of the C Language
- Declarations
- Statements
- Functions
- Preprocessor Directives
- C++ Programs
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of C Source Files ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example is a C program in two source files. The main and max
- functions are in separate files. The program starts running with the main
- function.
-
- Source file 1
-
- *
- ************************************************************************/
-
- /************************************************************************
- * Source file 1 - main function *
- ************************************************************************/
-
- #define ONE 1
- #define TWO 2
- #define THREE 3
-
- extern int max(int, int); /* Function declaration */
-
- int main(int argc, char * argv[]) /* Function definition */
- {
- int u, w, x, y, z;
-
- u = 5;
- z = 2;
- w = max(u, ONE);
- x = max(w,TWO);
- y = max(x,THREE);
- z = max(y,z);
- return z;
- }
-
- /************************************************************************
- *
-
- Source file 2
-
- *
- ************************************************************************/
-
- /************************************************************************
- * Source file 2 - max function *
- ************************************************************************/
- int max (int a,int b) /* Function definition */
-
- {
- if ( a > b )
- return (a);
- else
- return (b);
- }
-
- /************************************************************************
- *
-
- The first source file declares the function max, but does not define it. This
- is an external declaration, a declaration of a function defined in source file
- 2. Four statements in main are function calls of max.
-
- The lines beginning with a number sign (#) are preprocessor directives that
- direct the preprocessor to replace the identifiers ONE, TWO, and THREE with the
- digits 1, 2, and 3. The directives do not apply to the second source file.
-
- The second source file contains the function definition for max, which is
- called four times in main. After you compile the source files, you can link and
- run them as a single program.
-
- /************************************************************************
- *
-
-
- ΓòÉΓòÉΓòÉ 2.4. Program Execution ΓòÉΓòÉΓòÉ
-
- Every program must have a function called main and usually contains other
- functions.
-
- The main function is the starting point for running a program. The statements
- within the main function are executed sequentially. There may be calls to other
- functions. A program usually stops running at the end of the main function,
- although it can stop at other points in the program.
-
- You can make your program more modular by creating separate functions to
- perform a specific task or set of tasks. The main function calls these
- functions to perform the tasks. Whenever a function call is made, the
- statements are executed sequentially starting with the first statement in the
- function. The function returns control to the calling function at the return
- statement or at the end of the function.
-
- You can declare any function to have parameters. When functions are called,
- they receive values for their parameters from the arguments passed by the
- calling functions. You can declare parameters for the main function so you can
- pass values to main from the command line. The command line processor that
- starts the program can pass such values as described in The main() Function.
-
- Related Information
-
- Functions
- The main() Function
- Calling Functions and Passing Arguments
- C Source Files
- Overview of the C Language
- C++ Programs
-
-
- ΓòÉΓòÉΓòÉ 2.5. Scope in C ΓòÉΓòÉΓòÉ
-
- An identifier becomes visible with its declaration. The region where an
- identifier is visible is referred to as the identifier's scope. The four kinds
- of scope are:
-
- Block
- Function
- File
- Function prototype
-
- The scope of an identifier is determined by where the identifier is declared.
- See Identifiers for more information on identifiers.
-
- In the following example, the variable x, which is declared on line 1, is
- different from the x declared on line 2. The variable declared on line 2 has
- function prototype scope and is visible only up to the closing parenthesis of
- the prototype declaration. Visibility of the variable x declared on line 2
- resumes after the end of the prototype declaration.
-
- 1 int x = 4; /* variable x defined with file scope */
- 2 long myfunc(int x, long y); /* variable x has function */
- 3 /* prototype scope */
- 4 int main(void)
- 5 {
- 6 /* . . . */
- 7 }
-
- Functions with static storage class are visible only in the source file they
- are defined in. All other functions can be globally visible.
-
- Example of Scope
-
- Related Information
-
- Block
- Labels
- goto
- Functions
- static Storage Class Specifier
- C Source Files
- Scope in C++
-
-
- ΓòÉΓòÉΓòÉ <hidden> Block Scope ΓòÉΓòÉΓòÉ
-
- The identifier's declaration is located inside a statement block. A block
- starts with an opening brace ({) and ends with a closing brace (}). An
- identifier with block scope is visible from the point where it is declared to
- the closing brace that ends the block. Block scope is sometimes referred to as
- local scope.
-
- You can nest block visibility. A block nested inside a block can contain
- declarations that redeclare variables declared in the outer block. The new
- declaration of the variable applies to the inner block. The original
- declaration is restored when program control returns to the outer block. A
- variable from the outer block is visible inside inner blocks that do not
- redefine the variable.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Function Scope ΓòÉΓòÉΓòÉ
-
- The only type of identifier with function scope is a label name. A label is
- implicitly declared by its appearance in the program text and is visible
- throughout the function that declares it.
-
-
- ΓòÉΓòÉΓòÉ <hidden> File Scope ΓòÉΓòÉΓòÉ
-
- The identifier's declaration appears outside of any block. It is visible from
- the point where it is declared to the end of the source file. If source files
- are included by #include preprocessor directives, those files are considered to
- be part of the source and the identifier will be visible to all included files
- that appear after the declaration of the identifier. The identifier can be
- declared again as a block scope variable. The new declaration replaces the
- file-scope declaration until the end of the block.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Function Prototype Scope ΓòÉΓòÉΓòÉ
-
- The identifier's declaration appears within the list of parameters in a
- function prototype. It is visible from the point where it is declared to the
- closing parenthesis of the prototype declaration.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Scope ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program illustrates blocks, nesting, and scope. The example shows
- two kinds of scope: file and block. The main function prints the values 1, 2,
- 3, 0, 3, 2, 1 on separate lines. Each instance of i represents a different
- variable.
-
- *
- ************************************************************************/
-
- #include <stdio.h>
- int i = 1; /* i defined at file scope */
-
- int main(int argc, char * argv[])
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ {
- Γöé
- Γöé printf("%d\n", i); /* Prints 1 */
- Γöé
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇ {
- Γöé Γöé int i = 2, j = 3; /* i and j defined at
- Γöé Γöé block scope */
- Γöé Γöé printf("%d\n%d\n", i, j); /* Prints 2, 3 */
- Γöé Γöé
- Γöé Γöé ΓöîΓöÇΓöÇ {
- Γöé Γöé Γöé int i = 0; /* i is redefined in a nested block */
- Γöé Γöé Γöé /* previous definitions of i are hidden */
- Γöé Γöé Γöé printf("%d\n%d\n", i, j); /* Prints 0, 3 */
- Γöé Γöé ΓööΓöÇΓöÇ }
- Γöé Γöé
- Γöé Γöé printf("%d\n", i); /* Prints 2 */
- Γöé Γöé
- Γöé ΓööΓöÇΓöÇΓöÇΓöÇ }
- Γöé
- Γöé printf("%d\n", i); /* Prints 1 */
- Γöé
- Γöé return 0;
- Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ }
-
-
- ΓòÉΓòÉΓòÉ 2.6. Program Linkage ΓòÉΓòÉΓòÉ
-
- The association, or lack of association, between two identical identifiers is
- known as linkage. The kind of linkage that an identifier has depends on the way
- that it is declared.
-
- A file scope identifier has one of the following kinds of linkage:
-
- Internal Identical identifiers within a single source file refer to the
- same data object or function.
-
- External Identical identifiers in separately compiled files refer to
- the same data object or function.
-
- No linkage Each identical identifier refers to a unique object.
-
- Note: Program linkage is not the same as a function calling convention, which
- is also commonly referred to as linkage. While it is related to program
- linkage, a calling convention concerns itself with C++ linkage specifications
- and the use of certain keywords. This section discusses only program linkage.
-
- C++ Notes:
-
- Linkage specifications are used to link to non-C++ declarations.
-
- During compilation, the compiler encodes all function names and certain
- other identifiers to include type and scope information. This encoding
- process is called mangling, and the mangled names are used in the object
- files and final executable file. Tools that use these files must use the
- mangled names and not the original names used in the source code.
-
- VisualAge for C++ provides two methods of converting mangled names to the
- original source code names, demangling functions and the CPPFILT utility.
- The demangling functions are described in the appendix on Mapping in the
- IBM VisualAge for C++ for Windows User's Guide and in the <demangle.h>
- header file. The CPPFILT utility is described in the IBM VisualAge for
- C++ for Windows User's Guide.
-
- Related Information
-
- Internal Linkage
- External Linkage
- No Linkage
- Scope in C
- Declarations
-
-
- ΓòÉΓòÉΓòÉ <hidden> Internal Linkage ΓòÉΓòÉΓòÉ
-
- The following kinds of identifiers have internal linkage:
-
- All identifiers with file or block scope that have the keyword static in
- their declarations. Functions with static storage class are visible only
- in the source file in which you define them.
- Functions qualified with _Inline and C++ inline functions.
- C++ identifiers declared at file scope with the specifier const and not
- explicitly declared extern. In C, const objects have external linkage by
- default
-
- A variable that has static storage class can be defined within a block or
- outside a function. If the definition occurs within a block, the variable has
- internal linkage and is only visible within the block after its declaration is
- seen. If the definition occurs outside a function, the variable has internal
- linkage and is available from the point where it is defined to the end of the
- current source file.
-
- A class that has no static members or noninline member functions, and that has
- not been used in the declaration of an object or function or class is local to
- its compilation unit.
-
- If the declaration of an identifier has the keyword extern and if a previous
- declaration of the identifier is visible at file scope, the identifier has the
- same linkage as the first declaration.
-
-
- ΓòÉΓòÉΓòÉ <hidden> External Linkage ΓòÉΓòÉΓòÉ
-
- The following kinds of identifiers have external linkage:
-
- Identifiers with file or block scope that have the keyword extern in
- their declarations.
-
- If a previous declaration of the identifier is visible at file scope, the
- identifier has the same linkage as the first declaration. For example, a
- variable or function that is first declared with the keyword static and
- later declared with the keyword extern has internal linkage.
- Function identifiers declared without storage-class specifiers.
- Object identifiers that have file scope declarations without a
- storage-class specified. Storage is allocated for such object
- identifiers.
- Static class members and noninline member functions.
-
- Identifiers declared with the keyword extern can be defined in other
- compilation units.
-
- Related Information
-
- Program Linkage
- Internal Linkage
- No Linkage
- Storage Class Specifiers
-
-
- ΓòÉΓòÉΓòÉ <hidden> No Linkage ΓòÉΓòÉΓòÉ
-
- The following kinds of identifiers have no linkage:
-
- Identifiers that do not represent an object or a function, including
- labels, enumerators, typedef names, type names, and template names
- Identifiers that represent a function argument
- Identifiers declared inside a block without the keyword extern
-
- Related Information
-
- Program Linkage
- Internal Linkage
- External Linkage
- extern Storage Class Specifier
- Identifiers
-
-
- ΓòÉΓòÉΓòÉ 2.7. Storage Duration ΓòÉΓòÉΓòÉ
-
- Storage duration determines how long storage for an object exists. An object
- has either static storage duration or automatic storage duration depending on
- its declaration.
-
- Static storage Is allocated at initialization and remains available until
- the program ends. Objects have static storage duration if
- they:
-
- Have file scope
- Have external or internal linkage
-
- OR
- Contain the static storage class specifier.
-
- Automatic storage Is allocated and removed according to the scope of the
- identifier. Objects have automatic storage duration if
- they are:
-
- Parameters in a function definition.
- Declared at block scope and do not have any storage
- class specifier.
-
- OR
- Declared at block scope and have the register or auto
- storage class specifier.
-
- For example, storage for an object declared at block scope
- is allocated when the identifier is declared and removed
- when the closing brace (}) is reached.
-
- Note: Objects can also have heap storage duration. Heap objects are created
- at runtime and storage is allocated for them by calling a function such as
- malloc().
-
- Related Information
-
- Storage Class Specifiers
- Scope in C
- Program Linkage
-
-
- ΓòÉΓòÉΓòÉ 2.8. Name Spaces ΓòÉΓòÉΓòÉ
-
- The compiler sets up name spaces to distinguish among identifiers referring to
- different kinds of entities. Identical identifiers in different name spaces do
- not interfere with each other, even if they are in the same scope.
-
- You must assign unique names within each name space to avoid conflict. The same
- identifier can be used to declare different objects as long as each identifier
- is unique within its name space. The syntactic context of an identifier within
- a program lets the compiler resolve its name space without ambiguity.
-
- Identifiers in the same name space can be redefined within enclosed program
- blocks as described in Scope in C.
-
- Within each of the following four name spaces, the identifiers must be unique.
-
- Tags of these types must be unique within a single scope:
-
- - Enumerations
- - Structures and unions
-
- Members of structures, unions, and classes must be unique within a single
- structure, union or class type.
-
- Statement labels have function scope and must be unique within a
- function.
-
- All other ordinary identifiers must be unique within a single scope:
-
- - Function names
- - Variable names
- - Names of function parameters
- - Enumeration constants
- - typedef names.
-
- Structure tags, structure members, variable names, and statement labels are in
- four different name spaces; no conflict occurs among the four items named
- student in the following example:
-
- int get_item()
- {
- struct student /* structure tag */
- {
- char student[20]; /* structure member */
- int section;
- int id;
- } student; /* structure variable */
-
- goto student;
- student: ; /* null statement label */
- return (0);
- }
-
- Each occurrence of student is interpreted by its context in the program. For
- example, when student appears after the keyword struct, it is a structure tag.
- When student appears after either of the member selection operators . or ->,
- the name refers to the structure member. When student appears after the goto
- statement, control is passed to the null statement label. In other contexts,
- the identifier student refers to the structure variable.
-
- Related Information
-
- Scope in C
- Identifiers
- Type Specifiers
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ 2.9. Overview of the C++ Language ΓòÉΓòÉΓòÉ
-
- C++ is an object-oriented language based on the C programming language. It can
- be viewed as a superset of C. Almost all of the features and constructs
- available in C are also available in C++. However, C++ is more than just an
- extension of C. Its additional features support the programming style known as
- object-oriented programming. Several features that are already available in C,
- such as input and output may be implemented differently in C++. In C++ you may
- use the conventional C input and output routines or you may use object oriented
- input and output by using the I/O Stream class library.
-
- C++ was developed by Bjarne Stroustrup of AT&T Bell Laboratories. It was
- originally based on the definition of the C language stated in The C
- Programming Language by Brian W. Kernighan and Dennis M. Ritchie. This C
- language definition is commonly called K&R C. Since then, the International
- Standards Organization C language definition (referred to here as ANSI/ISO C)
- has been approved. It specifies many of the features that K&R left unspecified.
- Some features of ANSI/ISO C have been incorporated into the current definition
- of C++, and some parts of the ANSI/ISO C definition have been motivated by C++.
-
- While there is currently no C++ standard comparable to the ANSI/ISO C
- definition, an ISO committee is working on such a definition. The draft of the
- Working Paper for Draft Proposed American National Standard for Information
- Systems-Programming Language C++, X3J16/95-0087, is the base document for the
- ongoing standardization of C++. The VisualAge for C++ compiler adheres to most
- aspects of the language specified in the ANSI/ISO working paper dated April 28,
- 1995.
-
-
- ΓòÉΓòÉΓòÉ 2.10. C++ Support for Object-Oriented Programming ΓòÉΓòÉΓòÉ
-
- Object-oriented programming is based on the concepts of data abstraction,
- inheritance, and polymorphism. Unlike procedural programming, it concentrates
- on the data objects that are involved in a problem and how they are
- manipulated, not on how something is accomplished. Based on the foundation of
- data abstraction, object-oriented programming allows you to reuse existing code
- more efficiently and increase your productivity.
-
- Data Abstraction
- Encapsulation
- Inheritance
- Dynamic Binding and Polymorphism
- Other Features of C++
-
- Related Information
-
- C++ Classes
- Member Access
- Inheritance Overview
- Derivation
- Overview of the C++ Language
-
-
- ΓòÉΓòÉΓòÉ <hidden> Data Abstraction ΓòÉΓòÉΓòÉ
-
- Data abstraction provides the foundation for object-oriented programming. In
- addition to providing fundamental data types, object-oriented programming
- languages allow you to define your own data types, called user-defined or
- abstract data types. In the C programming language, related data items can be
- organized into structures. These structures can then be manipulated as units of
- data. In addition to providing this type of data structure, object-oriented
- programming languages allow you to implement a set of operations that can be
- applied to the data elements. The data elements and the set of operations
- applicable to the data elements together form the abstract data type.
-
- To support data abstraction, a programming language must provide a construct
- that can be used to encapsulate the data elements and operations that make up
- an abstract data type. In C++, this construct is called a class. An instance of
- a class is called an object. Classes are composed of data elements called data
- members and member functions that define the operations that can be carried out
- on the data members.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Encapsulation ΓòÉΓòÉΓòÉ
-
- Another key feature of object-oriented programming is encapsulation.
- Encapsulation means a class can hide the details of:
-
- The representation of its data members
- The implementation of the operations that can be performed on these data
- members
-
- Application programs manipulate objects of a class using a clearly defined
- interface. As long as this interface does not change, you can change the
- implementation of a class without having to change the application programs
- that use the class. Encapsulation provides the following advantages:
-
- Users of a class do not have to deal with unnecessary implementation
- details.
- Programs are easier to debug and maintain.
- Permitted alterations are clearly specified.
-
- In C++, encapsulation is accomplished by specifying the level of access for
- each member of a class. Both the data members and member functions of a class
- can be declared public, protected, or private depending on the kind of access
- required.
-
- Note: C++ encapsulation is not a true security mechanism. It is possible to
- circumvent the class access controls that make encapsulation possible. The
- language is not designed to prevent such misuse.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Inheritance ΓòÉΓòÉΓòÉ
-
- Inheritance lets you reuse existing code and data structures in new
- applications. In C++, inheritance is implemented through class derivation. You
- can extend a library of existing classes by adding data elements and operations
- to existing classes to form derived classes. A derived class has all the
- members of its parent or base class, as well as extensions that can provide
- additional features. When you create a new derived class, you only have to
- write the code for the additional features. The existing features of the base
- class are already available.
-
- A base class can have more than one class derived from it. In addition, a
- derived class can serve as a base class for other derived classes in a
- hierarchy. Typically, a derived class is more specialized than its base class.
-
- A derived class can inherit data members and member functions from more than
- one base class. Inheritance from more than one base class is called multiple
- inheritance.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Dynamic Binding and Polymorphism ΓòÉΓòÉΓòÉ
-
- Another key concept that allows you to write generic programs is dynamic or
- late binding. Dynamic binding allows a member function call to be resolved at
- run time, according to the run-time type of an object reference. This permits
- each user-defined class in an inheritance hierarchy to have a different
- implementation of a particular function. Application programs can then apply
- that function to an object without needing to know the specifics of the class
- that the object belongs to.
-
- In C++, dynamic binding hides the differences between a group of classes in an
- inheritance hierarchy from the application program. At run time, the system
- determines the specific class of the object and invokes the appropriate
- function implementation for that class.
-
- Dynamic binding is distinguished from static or compile-time binding, which
- involves compile-time member function resolution according to the static type
- of an object reference.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Other Features of C++ ΓòÉΓòÉΓòÉ
-
- C++ provides several other powerful extensions to the C programming language.
- Among these are:
-
- Constructors and destructors, which are used to create, initialize and
- destroy class objects
- Overloaded functions and operators, which let you extend the operations a
- function or operator can perform on different data types
- Inline functions, which make programs more efficient
- References, which allow a function to modify its arguments in the calling
- function
- Template functions and classes, which allow the definition of generic
- classes and functions
- Object-Oriented Exception handling, which provides transfer of control
- and recovery from errors and other exceptional circumstances
-
-
- ΓòÉΓòÉΓòÉ 2.11. C++ Programs ΓòÉΓòÉΓòÉ
-
- C++ programs contain many of the same programming statements and constructs as
- C programs:
-
- C++ has the same fundamental types (built-in) data types as C, as well as
- some types that are not built-in to C.
- Like ANSI/ISO C, C++ allows you to declare new type names by using the
- typedef construct. These new type names are not new types.
- In general, the scope and storage class rules for C also apply in C++.
- C and C++ have the same set of arithmetic and logical operators.
-
- A C++ name can identify any of the following:
-
- an object
- a function
- a set of functions
- an enumerator
- a type
- a class member
- a template
- a value
- a label
-
- A declaration introduces a name into a program and can define an area of
- storage associated with that name.
-
- An expression can be evaluated and is composed of operations and operands. An
- expression ending with a ; (semicolon) is called a statement. A statement is
- the smallest independent computational unit. Functions are composed of groups
- of one or more statements.
-
- A C++ program is composed of one or more functions. These functions can all
- reside in a single file or can be placed in different files that are linked to
- each other. In C++, a program must have one and only one non-member function
- called main().
-
- Source for a Simple C++ Program
-
- Related Information
-
- C++ Support for Object-Oriented Programming
- Overview of the C Language
- C Source Files
- C Source Programs
-
-
- ΓòÉΓòÉΓòÉ <hidden> Source for a Simple C++ Program ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following is a simple C++ program containing declarations, expressions,
- statements, and two functions:
-
- *
- ************************************************************************/
-
- /**
- ** A simple C++ program containing declarations,
- ** expressions, statements, and two functions:
- **/
-
- #include <math.h> // contains definition of abs()
- double multiplier, common_ratio; // variable declarations
- double geo_series(double a, double r) // function definition
- {
- if (r == 1) // if statement
- return -1.0; // return statement
- else if (abs(r) < 1.0) // else if statement
- return (a / (1 - r)); // statement containing
- // expression
- else return -2.0;
- }
- int main() // program execution begins here
- {
- double sum; // variable declaration
- multiplier = 2.2; // initialization of external variable
- common_ratio = 3.1; // initialization of external variable
- sum = geo_series(multiplier, common_ratio); // function call
- // ..
- return 0;
- }
-
-
- ΓòÉΓòÉΓòÉ 2.12. Scope in C++ ΓòÉΓòÉΓòÉ
-
- The area of the code where an identifier is visible is referred to as the scope
- of the identifier. The four kinds of scope are:
-
- Local
- Function
- File
- Class
-
- The scope of a name is determined by the location of the name's declaration.
-
- A type name first declared in a function return type has file scope. A type
- name first declared in a function argument list has local scope.
-
- A function name that is first declared as a friend of a class is in the first
- nonclass scope that encloses the class.
-
- If the friend function is a member of another class, it has the scope of that
- class. The scope of a class name first declared as a friend of a class is the
- first nonclass enclosing scope.
-
- Related Information
-
- Scope in C
- Friend Scope
- Scope of Class Names
- Member Scope
-
-
- ΓòÉΓòÉΓòÉ <hidden> Local Scope ΓòÉΓòÉΓòÉ
-
- A name has local scope if it is declared in a block. A name with local scope
- can be used in that block and in blocks enclosed within that block, but the
- name must be declared before it is used. When the block is exited, the names
- declared in the block are no longer available.
-
- Formal argument names for a function have the scope of the outermost block of
- that function.
-
- If a local variable is a class object with a destructor, the destructor is
- called when control passes out of the block in which the class object was
- constructed.
-
- When one block is nested inside another, the variables from the outer block are
- usually visible in the nested block. However, if an outer block variable is
- redefined in a nested block, the new declaration is in effect in the inner
- block. The original declaration is restored when program control returns to the
- outer block. This is called block visibility.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Function Scope ΓòÉΓòÉΓòÉ
-
- The only type of identifier with function scope is a label name. A label is
- implicitly declared by its appearance in the program text and is visible
- throughout the function that declares it.
-
-
- ΓòÉΓòÉΓòÉ <hidden> File Scope ΓòÉΓòÉΓòÉ
-
- A name has file scope if its declaration appears outside of all blocks and
- classes. A name with file scope is visible from the point where it is declared
- to the end of the source file. The name is also made accessible for the
- initialization of global variables. If a name is declared extern, it is also
- visible, at link time, in all object files being linked. Global names are names
- declared with file scope.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Class Scope ΓòÉΓòÉΓòÉ
-
- The name of a class member has class scope and can only be used in the
- following cases:
-
- In a member function of that class
- In a member function of a class derived from that class
- After the . (dot) operator applied to an instance of that class
- After the . (dot) operator applied to an instance of a class derived from
- that class
- After the -> (arrow) operator applied to a pointer to an instance of that
- class
- After the -> (arrow) operator applied to a pointer to an instance of a
- class derived from that class
- After the :: (scope resolution) operator applied to the name of a class
- After the :: (scope resolution) operator applied to a class derived from
- that class.
-
- For more information on class scope, see Scope of Class Names.
-
-
- ΓòÉΓòÉΓòÉ 2.13. Simple C++ Input and Output ΓòÉΓòÉΓòÉ
-
- Like C, the C++ language has no built-in input and output facilities. Instead,
- input and output facilities for C++ are provided by the I/O Stream Library. For
- compatibility with C, C++ also supports the standard I/O functions of C. The
- I/O Stream Library supports a set of I/O operations, written in the C++
- language, for the built-in types. You can extend these facilities to provide
- input and output functions for user-defined data types. For a complete
- description of the I/O Stream Library, see the Standard Class Library Guide.
-
- There are four predefined I/O stream objects that you can use to perform
- standard I/O:
-
- cout
- cin
- cerr
- clog
-
- You can use these in conjunction with the overloaded << (insertion or output)
- and >> (extraction or input) operators. To use these streams and operators,
- you must include the header file iostream.h. The following example prints
- Hello World! to standard output:
-
- /**
- ** Hello World
- **/
-
- #include <iostream.h>
- void main()
- {
- cout << "Hello World!" << endl;
- }
-
- The manipulator endl acts as a newline character, causing any output following
- it to be directed to the next line. Because it also causes any buffered output
- to be flushed, endl is preferred over \n to end lines.
-
- Related Information
-
- Overview of the C++ Language
- Overview of the C Language
- Overloading Operators
-
-
- ΓòÉΓòÉΓòÉ <hidden> cout ΓòÉΓòÉΓòÉ
-
- The cout stream is associated with standard output. You can use the output
- operator in conjunction with cout to direct a value to standard output.
- Successive output operators are concatenated when applied to cout. The
- following example prints out three strings in a row and produces the same
- result as the previous example, printing Hello World! to standard output.
-
- /**
- ** Another Hello World, illustrating concatenation with cout
- **/
-
- #include <iostream.h>
- void main()
- {
- cout << "Hello "
- << "World"
- << "!"
- << endl;
- }
-
- Output operators are defined to accept arguments of any of the fundamental data
- types, as well as pointers, references, and array types. You can also overload
- the output operator to define output for your own class types.
-
-
- ΓòÉΓòÉΓòÉ <hidden> cerr and clog ΓòÉΓòÉΓòÉ
-
- The cerr and clog streams direct output to standard error. cerr provides
- unbuffered output, while clog provides buffered output. The following example
- checks for a division by zero condition. If one occurs, a message is sent to
- standard error.
-
- /**
- ** Check for a division by zero condition.
- ** If one occurs, a message is sent to standard error.
- **/
-
- #include <iostream.h>
- void main()
- {
- double val1, val2;
- cout << "Divide Two Values" << endl;
- cout << "Enter two numeric values: " << endl;
- cin >> val1 >> val2;
- if (val2 == 0 )
- {
- cerr << "The second value must be non-zero" << endl;
- } else
- cout << "The answer is " << val1 / val2 << endl;
- }
-
-
- ΓòÉΓòÉΓòÉ <hidden> cin ΓòÉΓòÉΓòÉ
-
- The cin class object is associated with standard input. You can use the input
- operator in conjunction with cin to read a value from standard input. By
- default, white space (including blanks, tabs, and new lines) is disregarded by
- the input operator. For example:
-
- /**
- ** This example illustrates the cin operator
- **/
-
- #include <iostream.h>
- main()
- {
- double val1, val2;
- cout << "Enter two numeric values:" << endl;
- cin >> val1 >> val2;
- cout << "The first value entered is " << val1
- << " and the second value is "
- << val2 << "." << endl;
- }
-
- If the values 1.2 and 3.4 are entered through standard input, the above program
- prints the following to standard output:
-
- Enter two numeric values:
- 1.2
- 3.4
- The first value entered is 1.2 and the second value is 3.4.
-
- Any white space entered between the two numeric values is disregarded by the
- input operator.
-
- The input operator is defined to accept arguments of any of the fundamental
- data types, as well as pointers, references and array types. You can also
- overload the input operator to define input for your own class types.
-
-
- ΓòÉΓòÉΓòÉ 2.14. Linkage Specifications - Linking to non-C++ Programs ΓòÉΓòÉΓòÉ
-
- You can link C++ object modules to object modules produced using other source
- languages such as C and Fortran by using a linkage specification.
-
- The syntax is:
-
- >>ΓöÇΓöÇexternΓöÇΓöÇstring-literalΓöÇΓöÇΓö¼ΓöÇdeclarationΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇ{ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ}ΓöÇΓöÿ
- ΓööΓöÇdeclarationΓöÇΓöÿ
-
- The string-literal is used to specify the linkage associated with a particular
- function. For example:
-
- /**
- ** This example illustrates linkage specifications
- **/
-
- extern "C" int printf(const char*,...);
- void main()
- {
- printf("hello\n");
- }
-
- Here the string-literal, "C", tells the compiler that the routine printf(const
- char*,...) has C linkage. Note that string literals used in linkage
- specifications are not case sensitive.
-
- Some valid values for string-literal are:
-
- "C++" Default
-
- "C" C type linkage
-
- If the value of string-literal is not recognized, C type linkage is used. For
- more information on linkage specifications, see the description of calling
- conventions in the IBM VisualAge for C++ for Windows Programming Guide.
-
- Related Information
-
- Overview of the C++ Language
- Overview of the C Language
-
-
- ΓòÉΓòÉΓòÉ 3. Lexical Elements of C and C++ ΓòÉΓòÉΓòÉ
-
- This section describes the following lexical elements of C and C++:
-
- Tokens
- Source Program Character Set
- Trigraph Sequences
- Escape Sequences
- Comments
- Identifiers
- Keywords
- Constants
-
-
- ΓòÉΓòÉΓòÉ 3.1. Tokens ΓòÉΓòÉΓòÉ
-
- Source code is treated during preprocessing and compilation as a sequence of
- tokens. There are five different types of tokens:
-
- Identifiers
- Keywords
- Literals
- Operators
- Other separators
-
- Adjacent identifiers, keywords and literals must be separated with white
- space. Other tokens should be separated by white space to make the source code
- more readable. White space includes blanks, horizontal and vertical tabs, new
- lines, form feeds and comments.
-
-
- ΓòÉΓòÉΓòÉ 3.2. Source Program Character Set ΓòÉΓòÉΓòÉ
-
- The following lists the basic character set that must be available at both
- compile and run time:
-
- The uppercase and lowercase letters of the English alphabet
- The decimal digits 0 through 9
- The following graphic characters:
-
- ! " # % & ' ( ) * + , - . / :
- ; < = > ? [ \ ] _ { } ~
-
- The caret (^) character
- The split vertical bar (Γûî) character
- The space character
- The control characters representing new-line, horizontal tab, vertical
- tab, and form feed, and end of string (NULL character).
-
- The # (number sign) character is used for preprocessing only, and the _
- (underscore) character is treated as a normal letter.
-
- In extended and compatible language levels, the compiler allows the $ (dollar
- sign) character in C++ identifiers to facilitate calls between different
- languages and porting code. In ansi language level, the $ (dollar sign)
- character is not permitted in C++ identifiers. The default language level for
- the compiler is extended. Language level is set with the #pragma langlvl or
- the /S option.
-
- Related Information
-
- Trigraph Sequences
- /Ss option
-
-
- ΓòÉΓòÉΓòÉ <hidden> Trigraph Sequences ΓòÉΓòÉΓòÉ
-
- Some characters from the C character set are not available in all environments.
- You can enter these characters into a C source program using a sequence of
- three characters called a trigraph. The trigraph sequences are:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé "??=" Γöé "#" Γöé pound sign Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??(" Γöé "[" Γöé left bracket Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??)" Γöé "]" Γöé right bracket Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??<" Γöé "{" Γöé left brace Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??>" Γöé "}" Γöé right brace Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??/" Γöé "\" Γöé backslash Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??'" Γöé "^" Γöé caret Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??!" Γöé "|" Γöé vertical bar Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "??-" Γöé "~" Γöé tilde Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The preprocessor replaces trigraph sequences with the corresponding
- single-character representation.
-
- Related Information
-
- Source Program Character Set
-
-
- ΓòÉΓòÉΓòÉ 3.2.1. Digraph Sequences ΓòÉΓòÉΓòÉ
-
- You can represent unavailable characters in a source program by using a
- combination of two keystrokes called a digraph sequence. Digraphs are read as
- tokens during the preprocessor phase. Digraphs can be created using macro
- concatenation. They are not replaced in string literals or in character
- literals. For example:
-
- char *s = "<%%>"; // stays "<%%>"
-
- switch (c)
- {
- case '<%' : { /* ... */ } // stays '<%'
- case '%>' : { /* ... */ } // stays '%>'
- }
-
- The digraph sequences are:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé "%%" Γöé "#" Γöé pound sign Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "<:" Γöé "[" Γöé left bracket Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé ":>" Γöé "]" Γöé right bracket Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "<%" Γöé "{" Γöé left brace Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "%>" Γöé "}" Γöé right brace Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "%:%:" Γöé "##" Γöé preprocessor macro concatenation operator Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The nodigraph option disables processing of digraphs. The digraph option is on
- by default.
-
- The digraph option is described in the IBM VisualAge for C++ for Windows User's
- Guide.
-
-
- ΓòÉΓòÉΓòÉ 3.3. Comments ΓòÉΓòÉΓòÉ
-
- Comments begin with the /* characters, end with the */ characters, and can span
- more than one line. You can put comments anywhere the language allows white
- space.
-
- Comments are replaced during preprocessing by a single space character.
-
- Multibyte characters can also be included within a comment.
-
- Note: The /* or */ characters found in a character constant or string literal
- do not start or end comments.
-
- In the following program, line 6 is a comment:
-
- 1 #include <stdio.h>
- 2
- 3 int main(void)
- 4 {
- 5 printf("This program has a comment.\n");
- 6 /* printf("This is a comment line and will not print.\n"); */
- 7 return 0;
- 8 }
-
- Because the comment on line 6 is equivalent to a space, the output of this
- program is:
-
- This program has a comment.
-
- Because the comment delimiters are inside a string literal, line 5 in the
- following program is not a comment.
-
- 1 #include <stdio.h>
- 2
- 3 int main(void)
- 4 {
- 5 printf("This program does not have \
- 6 /* NOT A COMMENT */ a comment.\n");
- 7 return 0;
- 8 }
-
- The output of the program is:
-
- This program does not have /* NOT A COMMENT */ a comment.
-
- You cannot nest comments. Each comment ends at the first occurrence of */.
-
- Related Information
-
- C++ Comments
- /Ss option
-
-
- ΓòÉΓòÉΓòÉ <hidden> C++ Comments ΓòÉΓòÉΓòÉ
-
- If the /Ss compiler option is in effect when you compile a C program, double
- slashes (//) also specify the beginning of a comment.
-
- This is the default for VisualAge for C++. C++ permits double-slash comments as
- part of the language definition.
-
- A C++ comment can span more than one physical source line if it is joined into
- one logical source line with line-continuation (\) characters. The backslash
- character can also be represented by a trigraph.
-
-
- ΓòÉΓòÉΓòÉ 3.4. Identifiers ΓòÉΓòÉΓòÉ
-
- Identifiers consist of an arbitrary number of letters or digits. They provide
- names for the following language elements:
-
- Functions
- Data objects
- Labels
- Tags
- Parameters
- Macros
- Typedefs
- Structure and union members.
-
-
- ΓòÉΓòÉΓòÉ 3.4.1. Significant Characters in Identifiers ΓòÉΓòÉΓòÉ
-
- There is no limit for the number of characters in an identifier. However, only
- the first several characters of identifiers may be significant. The following
- table shows the number of significant characters for several kinds of
- identifiers.
-
- Identifier Maximum Number of Significant Characters
- Static data objects 255 characters
- Static function names 255 characters
- External data objects 255 after name decoration for linkage conventions
- (254 characters before name decoration for linkage
- conventions)
- External function names 255 after name decoration for linkage conventions
- (243 characters before name decoration for
- __stdcall linkage convention, and 254 characters
- before name decoration for other linkage
- conventions)
-
-
- ΓòÉΓòÉΓòÉ 3.4.2. Case Sensitivity and Special Characters in Identifiers ΓòÉΓòÉΓòÉ
-
- The compiler distinguishes between uppercase and lowercase letters in
- identifiers. For example, PROFIT and profit represent different data objects.
-
- Note: By default, the VisualAge for C++ linker linkage editor is case
- sensitive. To force it to be case insensitive, use the /IGNORECASE linkage
- editor option, though you typically should not need to use this option. For
- complete portability, never use different case representations to refer to the
- same object.
-
- Avoid creating identifiers that begin with an underscore (_) for function names
- and variable names.
-
- The first character in an identifier must be a letter. The _ (underscore)
- character is considered a letter; however, identifiers beginning with an
- underscore are reserved by the compiler for identifiers at file scope.
-
- Identifiers that begin with two underscores or an underscore followed by a
- capital letter, are reserved in all contexts.
-
- Although the names of system calls and library functions are not reserved words
- if you do not include the appropriate headers, avoid using them as identifiers.
- Duplication of a predefined name can lead to confusion for the maintainers of
- your code and can cause errors at link time or run time. If you include a
- library in a program, be aware of the function names in that library to avoid
- name duplications.
-
- You should always include the appropriate headers when using standard library
- functions. At the extended and compatible language levels, C++ identifiers can
- contain the $ character.
-
- Related Information
-
- Name Spaces
- Overview of the C Language
- File Inclusion (#include)
-
-
- ΓòÉΓòÉΓòÉ 3.4.3. Keywords ΓòÉΓòÉΓòÉ
-
- Keywords are identifiers reserved by the language for special use. Although you
- can use them for preprocessor macro names, it is poor programming style. Only
- the exact spelling of keywords is reserved. For example, auto is reserved but
- AUTO is not. The following lists the keywords common to both the C and C++
- languages. These keywords are also included in the ANSI/ISO C language
- definition:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 1. Keywords Common to C and C++ Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé auto Γöé double Γöé int Γöé struct Γöé
- Γöé break Γöé else Γöé long Γöé switch Γöé
- Γöé case Γöé enum Γöé register Γöé typedef Γöé
- Γöé char Γöé extern Γöé return Γöé union Γöé
- Γöé const Γöé float Γöé short Γöé unsigned Γöé
- Γöé continue Γöé for Γöé signed Γöé void Γöé
- Γöé default Γöé goto Γöé sizeof Γöé volatile Γöé
- Γöé do Γöé if Γöé static Γöé while Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The C++ language also reserves the following keywords:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 2. C++ Keywords Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé asm Γöé friend Γöé protected Γöé try Γöé
- Γöé catch Γöé inline Γöé public Γöé typeid Γöé
- Γöé class Γöé new Γöé template Γöé virtual Γöé
- Γöé delete Γöé operator Γöé this Γöé wchar_t Γöé
- Γöé dynamic_cast Γöé private Γöé throw Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Although they are documented in the ANSI/ISO C++ Working Paper, and are
- reserved by the compiler, the following keywords are not yet supported by
- VisualAge for C++:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 3. C++ Language Keywords Not Supported by VisualAge for C++ Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé bool Γöé false Γöé reinterpret_cast Γöé typename Γöé
- Γöé const_cast Γöé mutable Γöé static_cast Γöé using Γöé
- Γöé explicit Γöé namespace Γöé true Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The VisualAge for C++ compiler also reserves the following keywords. They are
- VisualAge for C++ extensions to the existing language standards.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 4. Additional VisualAge for C++ Keywords Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé _Builtin Γöé _Far16 Γöé __import Γöé _Optlink Γöé __system Γöé
- Γöé __builtin Γöé __far16 Γöé __int64 Γöé __optlink Γöé __thread Γöé
- Γöé _Cdecl Γöé _Far32 Γöé _Inline Γöé _Pascal Γöé __try Γöé
- Γöé __cdecl Γöé __far32 Γöé __inline Γöé __pascal Γöé __unaligned Γöé
- Γöé __declspec Γöé _Fastcall Γöé __int8 Γöé _Packed Γöé Γöé
- Γöé _Export Γöé __fastcall Γöé __int16 Γöé __packed Γöé Γöé
- Γöé __export Γöé __finally Γöé __int32 Γöé __stdcall Γöé Γöé
- Γöé __except Γöé _Import Γöé __leave Γöé _System Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The following keywords are reserved only for C programs:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 5. Keywords for C Only Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé _FAR32 Γöé _PACKED Γöé __FINALLY Γöé Γöé
- Γöé __FAR32 Γöé __PACKED Γöé __LEAVE Γöé Γöé
- Γöé _INLINE Γöé __EXCEPT Γöé __TRY Γöé Γöé
- Γöé __INLINE Γöé Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The keywords used in the following function calling conventions are reserved by
- the compiler, but the calling conventions themselves are not supported by IBM
- VisualAge for C++ for Windows:
-
- _Pascal
- _Far32 _Pascal
- _Far16 _Cdecl
- _Far16 _Pascal
- _Far16 _Fastcall
- Using the keywords as calling conventions causes a warning to be issued.
-
- See Linkage Keywords for more information about linkage keywords for calling
- conventions.
-
- For compatibility with Microsoft Visual C++, the VisualAge for C++ compiler
- also reserves the following keywords in extended mode only:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 6. Additional VisualAge for C++ Keywords for Microsoft Compatibility Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé _asm Γöé _except Γöé _int16 Γöé _stdcall Γöé
- Γöé __asm Γöé _finally Γöé _int32 Γöé _try Γöé
- Γöé _cdecl Γöé _inline Γöé _int64 Γöé Γöé
- Γöé _declspec Γöé _int8 Γöé _leave Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The following keywords are reserved only for C programs:
-
- _except
- _finally
- _inline
- _leave
- _try
-
- If you include the <iso646.h> header, you can represent unavailable characters
- in a source program using the following keywords:
-
- Keyword Symbol
- bitand &
- and &&
- bitor |
- or ||
- xor ^
- compl ~
- and_eq &=
- or_eq |=
- xor_eq ^=
- not !
- not_eq !=
-
-
- ΓòÉΓòÉΓòÉ 3.4.3.1. _asm and __asm Keywords ΓòÉΓòÉΓòÉ
-
- Some compilers permit assembler code to be inlined using the keywords asm,
- _asm, and __asm. Declarations with asm are described in Assembler Declarations
- (asm Keyword).
-
- The _asm and __asm keywords can appear anywhere a C statement is permitted.
-
- The _asm and __asm keywords are recognized by VisualAge for C++ in extended
- mode only. However, no code is generated for the inlined assembler instructions
- and a warning is issued. They must be followed by:
-
- An assembler instruction followed by a new-line character
- An assembler instruction followed by another _asm or __asm statement.
- A block of assembler instructions enclosed in braces ({ })
- An empty pair of braces.
-
- Any preprocessor directives within a statement using the _asm or __asm
- keywords are interpreted and macros are expanded.
-
- Related Information
-
- _Packed Qualifier
- __unaligned Type Qualifier
- Linkage Keywords
- _Export Keyword
- Inline Specifiers
- Inline Functions
-
-
- ΓòÉΓòÉΓòÉ 3.5. Constants ΓòÉΓòÉΓòÉ
-
- A constant does not change its value while the program is running. The value of
- any constant must be in the range of representable values for its type.
-
- The C language contains the following types of constants (also called
- literals):
-
- Integer Constants
- Floating-Point Constants
- Character Constants
- String Literals
-
- Enumeration constants, which belong to the lexical class of identifiers, are
- discussed in Enumerations. For more information on data types, see Type
- Specifiers.
-
-
- ΓòÉΓòÉΓòÉ 3.5.1. Integer Constants ΓòÉΓòÉΓòÉ
-
- Integer constants can represent decimal, octal, or hexadecimal values. The data
- type of an integer constant is determined by the form, value, and suffix of the
- constant. The following lists the integer constants and shows the possible data
- types for each constant. The smallest data type that can represent the constant
- value is used to store the constant.
-
- Constant Data Type
- unsuffixed decimal int, long int, unsigned long int
- unsuffixed octal int, unsigned int, long int, unsigned
- long int
- unsuffixed hexadecimal int, unsigned int, long int, unsigned
- long int
- suffixed by u or U unsigned int, unsigned long int
- suffixed by l or L long int, unsigned long int
- suffixed by both u or U, and l or L unsigned long int
-
- A plus (+) or minus (-) symbol can precede the constant. It is treated as a
- unary operator rather than as part of the constant value.
-
- Related Information
-
- Decimal Constants
- Octal Constants
- Hexadecimal Constants
- Integer Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.1.1. Decimal Constants ΓòÉΓòÉΓòÉ
-
- A decimal constant contains any of the digits 0 through 9. The first digit
- cannot be 0. Integer constants beginning with the digit 0 are interpreted as an
- octal constant, rather than as a decimal constant.
-
- Related Information
-
- Integer Constants
- Octal Constants
- Hexadecimal Constants
- Integer Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.1.2. Hexadecimal Constants ΓòÉΓòÉΓòÉ
-
- A hexadecimal constant begins with the 0 digit followed by either an x or X,
- followed by any combination of the digits 0 through 9 and the letters a through
- f or A through F. The letters A (or a) through F (or f) represent the values 10
- through 15, respectively.
-
- The following are examples of hexadecimal constants:
-
- 0x3b24
- 0XF96
- 0x21
- 0x3AA
- 0X29b
- 0X4bD
-
- Related Information
-
- Integer Constants
- Decimal Constants
- Octal Constants
- Integer Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.1.3. Octal Constants ΓòÉΓòÉΓòÉ
-
- An octal constant begins with the digit 0 and contains any of the digits 0
- through 7.
-
- The following are examples of octal constants:
-
- 0
- 0125
- 034673
- 03245
-
- Related Information
-
- Integer Constants
- Decimal Constants
- Hexadecimal Constants
- Integer Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.2. Floating-Point Constants ΓòÉΓòÉΓòÉ
-
- A floating-point constant consists of:
-
- An integral part
- A decimal point
- A fractional part
- An exponent part
- An optional suffix.
-
- Both the integral and fractional parts are made up of decimal digits. You can
- omit either the integral part or the fractional part, but not both. You can
- omit either the decimal point or the exponent part, but not both.
-
- The representation of a floating-point number on a system is unspecified. If a
- floating-point constant is too large or too small, the result is undefined by
- the language. VisualAge for C++, represents floating-point numbers according
- to IEEE rules. For C, if a floating-point constant is too large, it is set to
- the largest value representable by the type. If it is too small, it is set to
- zero. For C++, constant values that are too large or too small cause a
- compile-time error.
-
- The suffix f or F indicates a type of float, and the suffix l or L indicates a
- type of long double. If a suffix is not specified, the floating-point constant
- has a type double.
-
- A plus (+) or minus (-) symbol can precede a floating-point constant. However,
- it is not part of the constant; it is interpreted as a unary operator.
-
- The following are examples of floating-point constants:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé FLOATING-POINT CON- Γöé VALUE Γöé
- Γöé STANT Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "5.3876e4" Γöé "53,876" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "4e-11" Γöé "0.00000000004" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "1e+5" Γöé "100000" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "7.321E-3" Γöé "0.007321" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "3.2E+4" Γöé "32000" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "0.5e-6" Γöé "0.0000005" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "0.45" Γöé "0.45" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "6.e10" Γöé "60000000000" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Related Information
-
- Floating-Point Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.3. Character Constants ΓòÉΓòÉΓòÉ
-
- A character constant contains a sequence of characters or escape sequences
- enclosed in single quotation mark symbols.
-
- At least one character or escape sequence must appear in the character
- constant. The characters can be any from the source program character set,
- excluding the single quotation mark, backslash and new-line symbols. The prefix
- L indicates a wide character constant. A character constant must appear on a
- single logical source line.
-
- The value of a character constant containing a single character is the numeric
- representation of the character in the character set used at run time. The
- value of a wide character constant containing a single multibyte character is
- the code for that character, as defined by the mbtowc function. If the
- character constant contains more than one character, the last 4 bytes represent
- the character constant. In C++, a character constant can contain only one
- character.
-
- In C, a character constant has type int. In C++, a character constant has type
- char.
-
- A wide character constant is represented by a double-byte character of type
- wchar_t. Multibyte characters represent character sets that use more than one
- byte in their representation. In Windows, each multibyte character can contain
- up to 2 bytes.
-
- Restrictions
-
- To represent the single quotation symbol, backslash, and new-line characters,
- you must use the corresponding escape sequence. For more information on escape
- sequences, see Escape Sequences.
-
- The following are examples of character constants:
-
- 'a' '\''
- '0' '('
- 'x' '\n'
- '7' '\117'
- 'C'
-
- Related Information
-
- String Literals
- Escape Sequences
- Integer Variables
-
-
- ΓòÉΓòÉΓòÉ 3.5.4. String Literals ΓòÉΓòÉΓòÉ
-
- A string constant or literal contains a sequence of characters or escape
- sequences enclosed in double quotation mark symbols.
-
- The prefix L indicates a wide-character string literal.
-
- A null ('\0') character is appended to each string. For a wide character string
- (a string prefixed by the letter L), the value '\0' of type wchar_t is
- appended. By convention, programs recognize the end of a string by finding the
- null character.
-
- Multiple spaces contained within a string constant are retained.
-
- To continue a string on the next line, use the line continuation sequence (\
- symbol immediately followed by a new-line character). A carriage return must
- immediately follow the backslash. In the following example, the string literal
- second causes a compile-time error.
-
- char *first = "This string continues onto the next\
- line, where it ends."; /* compiles successfully. */
- char *second = "The comment makes the \ /* continuation symbol */
- invisible to the compiler."; /* compilation error. */
-
- Another way to continue a string is to have two or more consecutive strings.
- Adjacent string literals are concatenated to produce a single string. You
- cannot concatenate a wide string constant with a character string constant. For
- example:
-
- "hello " "there" /* is equivalent to "hello there" */
- "hello " L"there" /* is not valid */
- "hello" "there" /* is equivalent to "hellothere" */
-
- Characters in concatenated strings remain distinct. For example, the strings
- "\xab" and "3" are concatenated to form "\xab3". However, the characters \xab
- and 3 remain distinct and are not merged to form the hexadecimal character
- \xab3.
-
- Following any concatenation, '\0' of type char is appended at the end of each
- string. C++ programs find the end of a string by scanning for this value. For a
- wide-character string literal, '\0' of type wchar_t is appended. For example:
-
- char *first = "Hello "; /* stored as "Hello \0" */
- char *second = "there"; /* stored as "there\0" */
- char *third = "Hello " "there"; /* stored as "Hello there\0" */
-
- A character string constant has type array of char and static storage duration.
- A wide character constant has type array of wchar_t and static storage
- duration.
-
- Use the escape sequence \n to represent a new-line character as part of the
- string. Use the escape sequence \\ to represent a backslash character as part
- of the string. You can represent the single quotation mark symbol by itself ',
- but you use the escape sequence \" to represent the double quotation mark
- symbol.
-
- For example:
-
- /**
- ** This example illustrates escape sequences in string literals
- **/
-
- #include <iostream.h>
- void main ()
- {
- char *s ="Hi there! \n";
- cout << s;
- char *p = "The backslash character \\.";
- cout << p << endl;
- char *q = "The double quotation mark \".\n";
- cout << q ;
- }
-
- This program produces the following output:
-
- Hi there!
- The backslash character \.
- The double quotation mark ".
-
- You should be careful when modifying string literals because the resulting
- behavior depends on whether your strings are stored in read/write static
- memory. Strings are readonly by default.
-
- Use the #pragma strings preprocessor directive to change the default storage
- for string literals.
-
- The following are examples of string literals:
-
- char titles[ ] = "Handel's \"Water Music\"";
- char *mail_addr = "Last Name First Name MI Street Address \
- City Province Postal code ";
- char *temp_string = "abc" "def" "ghi"; /* *temp_string = "abcdefghi\0" */
- wchar_t *wide_string = L"longstring";
-
- Related Information
-
- Character Constants
- Escape Sequences
- Characters
- Arrays
- Pragma Directives (#pragma)
- #pragma strings
-
-
- ΓòÉΓòÉΓòÉ 3.5.5. Escape Sequences ΓòÉΓòÉΓòÉ
-
- An escape sequence contains a backslash (\) symbol followed by one of the
- escape sequence characters or an octal or hexadecimal number. A hexadecimal
- escape sequence contains an x followed by one or more hexadecimal digits (0-9,
- A-F, a-f). An octal escape sequence uses up to three octal digits (0-7).
-
- Note: The line continuation sequence (\ followed by a new-line character) is
- not an escape sequence. It is used in character strings to indicate that the
- current line continues on the next line.
-
- The escape sequences and the characters they represent are:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé ESCAPE Γöé CHARACTER REPRES- Γöé
- Γöé SEQUENCE Γöé ENTED Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\a" Γöé Alert (bell, alarm) Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\b" Γöé Backspace Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\f" Γöé Form feed (new page) Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\n" Γöé New-line Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\r" Γöé Carriage return Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\t" Γöé Horizontal tab Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\v" Γöé Vertical tab Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\'" Γöé Single quotation Γöé
- Γöé Γöé mark Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\"" Γöé Double quotation Γöé
- Γöé Γöé mark Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\?" Γöé Question mark Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "\\" Γöé Backslash Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The value of an escape sequence represents the member of the character set used
- at run time. Escape sequences are translated during preprocessing. For example,
- on a system using the ASCII character codes, the value of the escape sequence
- \x56 is the letter V.
-
- Use escape sequences only in character constants or in string literals.
-
- If an escape sequence is not recognized, the compiler uses the character
- following the backslash and a message is issued. Note that this behavior is
- implementation-defined.
-
- In string and character sequences, when you want the backslash to represent
- itself (rather than the beginning of an escape sequence), you must use a \\
- backslash escape sequence. For example:
-
- cout << "The escape sequence \\n." << endl;
-
- This statement results in the following output:
-
- The escape sequence \n.
-
- The following program prints the character 'a' four times to standard output,
- and then prints a new line:
-
- #include <iostream.h>
- void main()
- {
- char a,b,c,d,e;
- a='a';
- b=97; // ASCII integer value
- c='\141'; // ASCII octal value
- d='\x61'; // ASCII hexadecimal value
- e='\n';
- cout << a << b << c << d << e;
- }
-
- Related Information
-
- Character Constants
- String Literals
-
-
- ΓòÉΓòÉΓòÉ 4. Declarations ΓòÉΓòÉΓòÉ
-
- A declaration establishes the names and characteristics of data objects and
- functions used in a program. A definition allocates storage for data objects or
- specifies the body for a function. When you define a type, no storage is
- allocated.
-
- Declarations determine the following properties of data objects and their
- identifiers:
-
- Scope, which describes the visibility of an identifier in a block or
- source file. For a complete description of scope, see Scope in C.
- Linkage, which describes the association between two identical
- identifiers. See Program Linkage for more information.
- Storage duration, which describes when the system allocates and frees
- storage for a data object. See Storage Duration for more information.
- Type, which describes the kind of data the object is to represent.
-
- The lexical order of elements of declaration for a data object is as follows:
-
- Storage duration and linkage specification, described in Storage Class
- Specifiers
- Type specification, described in Type Specifiers
- Declarators, which introduce identifiers and make use of type qualifiers
- and storage qualifiers, described in Declarators
- Initializers, which initialize storage with initial values, described in
- Initializers.
-
- Function declarations are described in Functions.
-
- Syntax of a Data Declaration
-
- Note:
-
- 1. One of the fundamental differences between C++ and C is the placement of
- variable declarations. Although variables are declared in the same way,
- in C++, variable declarations can be put anywhere in the program. In C,
- declarations must come before any statements in a block.
-
- In the following C++ example, the variable d is declared in the middle of
- the main() function:
-
- #include <iostream.h>
- void main()
- {
- int a, b;
- cout << "Please enter two integers" << endl;
- cin >> a >> b;
- int d = a + b;
- cout << "Here is the sum of your two integers:" << d << endl;
- }
-
- 2. A given function, object, or type can have only one definition. It can
- have more than one declaration as long as all of the declarations match.
- If a function is never called and its address is never taken, then you do
- not have to define it. If an object is declared but never used, or is
- only used as the operand of sizeof, you do not have to define it. You can
- declare a given class or enumerator more than once.
-
- The following table shows examples of declarations and definitions.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 7. Examples of Declarations and Definitions Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé DECLARATIONS Γöé DECLARATIONS AND DEFINITIONS Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "extern double pi;" Γöé "double pi = 3.14159265;" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "float square(float x);" Γöé "float square(float x) { return x*x; }" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "struct payroll;" Γöé struct payroll { Γöé
- Γöé Γöé char *name; Γöé
- Γöé Γöé float salary; Γöé
- Γöé Γöé } employee; Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Related Information
-
- Block Scope Data Declarations
- File Scope Data Declarations
- Declarators
- Storage Class Specifiers
- Initializers
- Type Specifiers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Data Declaration Syntax ΓòÉΓòÉΓòÉ
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Γöé
- >>ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇΓöÇΓöÇdeclaratorΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓö┤ΓöÇΓöÇ;ΓöÇΓöÇ><
- Γö£ΓöÇstorage_class_specifierΓöÇΓöñ ΓööΓöÇinitializerΓöÇΓöÿ
- Γö£ΓöÇtype_specifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇtype_qualifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.1. Block Scope Data Declarations ΓòÉΓòÉΓòÉ
-
- A block scope data declaration can only be put at the beginning of a block. It
- describes a variable and makes that variable accessible to the current block.
- All block scope declarations that do not have the extern storage class
- specifier are definitions and allocate storage for that object.
-
- You can declare a data object with block scope with any of the storage class
- specifiers described in Storage Class Specifiers. If you do not specify a
- storage class specifier in a block-scope data declaration, the default storage
- class specifier auto is used. If you specify a storage class specifier, you can
- omit the type specifier. If you omit the type specifier, all variables in that
- declaration receive type int.
-
- Initialization
- You cannot initialize a variable declared in a block scope data declaration
- that has the extern storage class specifier.
-
- The types of variables you can initialize and the values that uninitialized
- variables receive vary for that storage class specifier. See Storage Class
- Specifiers for details on the different storage classes.
-
- Storage
-
- The duration and type of storage varies for each storage class specifier.
-
- Declarations with the auto or register storage class specifier result in
- automatic storage duration. Declarations with the extern or static storage
- class specifier result in static storage duration.
-
- Related Information
-
- Declarators
- Storage Class Specifiers
- auto Storage Class Specifier
- extern Storage Class Specifier
- register Storage Class Specifier
- static Storage Class Specifier
- Declarations
- Initializers
- Type Specifiers
-
-
- ΓòÉΓòÉΓòÉ 4.2. File Scope Data Declarations ΓòÉΓòÉΓòÉ
-
- A file scope data declaration appears outside any function definition. It
- describes a variable and makes that variable accessible to all functions that
- are in the same file and whose definitions appear after the declaration.
-
- A file scope data definition is a data declaration at file scope that also
- causes storage to be allocated for that variable. All objects whose identifiers
- are declared at file scope have static storage duration.
-
- Use a file scope data declaration to declare variables that you want to have
- external linkage.
-
- The only storage class specifiers you can put in a file scope data declaration
- are static, extern, and typedef. If you specify static, all variables defined
- in it have internal linkage. If you do not specify static, all variables
- defined in it have external linkage. If you specify the storage class you can
- omit the type specifier. If you omit the type specifier, all variables defined
- in that declaration receive the type int.
-
- Initialization
- You can initialize any object with file scope. If you do not initialize a file
- scope variable, its initial value is zero of the appropriate type. If you do
- initialize it, the initializer must be described by a constant expression, or
- it must reduce to the address of a previously declared variable at file scope,
- possibly modified by a constant expression. Initialization of all variables at
- file scope takes place before the main function begins running.
-
- Storage
- All objects with file scope data declarations have static storage duration.
- Storage is allocated at runtime and freed when the program stops running.
-
- Related Information
-
- extern Storage Class Specifier
- static Storage Class Specifier
- Declarations
- Declarators
- Initializers
- Type Specifiers
-
-
- ΓòÉΓòÉΓòÉ 4.3. Objects ΓòÉΓòÉΓòÉ
-
- An object is a region of storage that contains a value or group of values. Each
- value can be accessed using its identifier or a more complex expression that
- refers to the object. In addition, each object has a unique data type. Both the
- identifier and data type of an object are established in the object
- declaration.
-
- The data type of an object determines the initial storage allocation for that
- object and the interpretation of the values during subsequent access. It is
- also used in any type-checking operations.
-
- C++ has built-in, or standard, data types and user-defined data types. Standard
- data types include signed and unsigned integers, floating-point numbers, and
- characters. User-defined types include enumerations, structures, unions, and
- classes.
-
- In C++ code, objects are represented by variables. A variable also represents
- the location in storage that contains the value of an object.
-
- An instance of a class type is commonly called a class object. The individual
- class members are also called objects. The set of all member objects comprises
- a class object.
-
- Related Information
-
- Type Specifiers
- C++ Classes
- Declarations
-
-
- ΓòÉΓòÉΓòÉ 4.4. Storage Class Specifiers ΓòÉΓòÉΓòÉ
-
- The storage class specifier used within the declaration determines whether:
-
- The object has internal, external, or no linkage.
-
- The object is to be stored in memory or in a register, if available.
-
- The object receives the default initial value 0 or an indeterminate
- default initial value.
-
- The object can be referenced throughout a program or only within the
- function, block, or source file where the variable is defined.
-
- The storage duration for the object is static (storage is maintained
- throughout program run time) or automatic (storage is maintained only
- during the execution of the block where the object is defined).
-
- For a function, the storage class specifier determines the linkage of the
- function.
-
- Declarations with the auto or register storage-class specifier result in
- automatic storage. Those with the extern or static storage-class specifier
- result in static storage.
-
- Most local declarations that do not include the extern storage-class specifier
- allocate storage; however, function declarations and type declarations do not
- allocate storage.
-
- The only storage-class specifiers allowed in a global or file scope
- declaration are static and extern.
-
- The VisualAge for C++ compiler implements additional storage class specifiers
- for inlining functions:
-
- inline for C++ functions
- _Inline, _inline, and __inline specifiers for C functions
- The inlining specifiers determine whether the function code will be inlined or
- called. Note that they are ignored if the /Oi- compiler option is specified.
-
- The following sections describe the storage class specifiers:
-
- auto Storage Class Specifier
- extern Storage Class Specifier
- register Storage Class Specifier
- static Storage Class Specifier
- typedef
-
- Related Information
-
- Program Linkage
- Inline Functions
- Declarations
- Inline Specifiers
- /Oi option
-
-
- ΓòÉΓòÉΓòÉ 4.4.1. auto Storage Class Specifier ΓòÉΓòÉΓòÉ
-
- The auto storage class specifier lets you define a variable with automatic
- storage; its use and storage is restricted to the current block. The storage
- class keyword auto is optional in a data declaration. It is not permitted in a
- parameter declaration. A variable having the auto storage class specifier must
- be declared within a block. It cannot be used for file scope declarations.
-
- Because automatic variables require storage only while they are actually being
- used, defining variables with the auto storage class can decrease the amount of
- memory required to run a program. However, having many large automatic objects
- may cause you to run out of stack space.
-
- Declaring variables with the auto storage class can also make code easier to
- maintain, because a change to an auto variable in one function never affects
- another function (unless it is passed as an argument).
-
- You can initialize any auto variable except parameters. If you do not
- initialize an automatic object, its value is indeterminate. If you provide an
- initial value, the expression representing the initial value can be any valid C
- or C++ expression. For structure and union members, the initial value must be a
- valid constant expression if an initializer list is used. The object is then
- set to that initial value each time the program block that contains the
- object's definition is entered.
-
- Note: If you use the goto statement to jump into the middle of a block,
- automatic variables within that block are not initialized.
-
- Objects with the auto storage class specifier have automatic storage duration.
- Each time a block is entered, storage for auto objects defined in that block is
- made available. When the block is exited, the objects are no longer available
- for use.
-
- If an auto object is defined within a function that is recursively invoked,
- memory is allocated for the object at each invocation of the block.
-
- Examples of auto Storage Class
-
- Related Information
-
- Storage Class Specifiers
- register Storage Class Specifier
- Block Scope Data Declarations
- Function Declarator
- Address &
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of auto Storage Class ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program shows the scope and initialization of auto variables. The
- function main defines two variables, each named auto_var. The first definition
- occurs on line 10. The second definition occurs in a nested block on line 13.
- While the nested block is running, only the auto_var created by the second
- definition is available. During the rest of the program, only the auto_var
- created by the first definition is available.
-
- *
- ************************************************************************/
-
- 1 /****************************************************
- 2 ** Example illustrating the use of auto variables **
- 3 ****************************************************/
- 4
- 5 #include <stdio.h>
- 6
- 7 int main(void)
- 8 {
- 9 void call_func(int passed_var);
- 10 auto int auto_var = 1; /* first definition of auto_var */
- 11
- 12 {
- 13 int auto_var = 2; /* second definition of auto_var */
- 14 printf("inner auto_var = %d\n", auto_var);
- 15 }
- 16 call_func(auto_var);
- 17 printf("outer auto_var = %d\n", auto_var);
- 18 return 0;
- 19 }
- 20
- 21 void call_func(int passed_var)
- 22 {
- 23 printf("passed_var = %d\n", passed_var);
- 24 passed_var = 3;
- 25 printf("passed_var = %d\n", passed_var);
- 26 }
-
- /************************************************************************
- *
- This program produces the following output:
-
- inner auto_var = 2
- passed_var = 1
- passed_var = 3
- outer auto_var = 1
-
- The following example uses an array that has the storage class auto to pass a
- character string to the function sort. The function sort receives the address
- of the character string, rather than the contents of the array. The address
- enables sort to change the values of the elements in the array.
-
- *
- ************************************************************************/
-
- /*****************************************************************
- ** Sorted string program -- this example passes an array name **
- ** to a function **
- *****************************************************************/
-
- #include <stdio.h>
- #include <string.h>
-
- int main(void)
- {
- void sort(char *array, int n);
- char string[75];
- int length;
-
- printf("Enter letters:\n");
- scanf("%74s", string);
- length = strlen(string);
- sort(string,length);
- printf("The sorted string is: %s\n", string);
-
- return(0);
- }
-
- void sort(char *array, int n)
- {
- int gap, i, j, temp;
-
- for (gap = n / 2; gap > 0; gap /= 2)
- for (i = gap; i < n; i++)
- for (j = i - gap; j >= 0 && array[j] > array[j + gap];
- j -= gap)
- {
- temp = array[j];
- array[j] = array[j + gap];
- array[j + gap] = temp;
- }
- }
-
- /**********************************************************************************
- *
-
- When the program is run, interaction with the program could produce:
-
- Output Enter letters:
-
- Input zyfab
-
- Output The sorted string is: abfyz
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.4.2. extern Storage Class Specifier ΓòÉΓòÉΓòÉ
-
- The extern storage class specifier lets you declare objects and functions that
- several source files can use. All object declarations that occur outside a
- function and that do not contain a storage class specifier declare identifiers
- with external linkage. All function definitions that do not specify a storage
- class define functions with external linkage.
-
- You can distinguish an extern declaration from an extern definition by the
- presence of the keyword extern and the absence of an initial value. If the
- keyword extern is absent or if there is an initial value, the declaration is
- also a definition; otherwise, it is just a declaration. An extern definition
- can appear only at file scope.
-
- An extern variable, function definition, or declaration also makes the
- described variable or function usable by the succeeding part of the current
- source file. This declaration does not replace the definition. The declaration
- is used to describe the variable that is externally defined.
-
- If a declaration for an identifier already exists at file scope, any extern
- declaration of the same identifier found within a block refers to that same
- object. If no other declaration for the identifier exists at file scope, the
- identifier has external linkage.
-
- An extern declaration can appear outside a function or at the beginning of a
- block. If the declaration describes a function or appears outside a function
- and describes an object with external linkage, the keyword extern is optional.
-
- C++ Note: In C++, an extern declaration cannot appear in class scope.
-
- You can initialize any object with the extern storage class specifier at file
- scope. You can initialize an extern object with an initializer that must
- either:
-
- Appear as part of the definition and the initial value must be described
- by a constant expression.
-
- OR
- Reduce to the address of a previously declared object with static storage
- duration. This object may be modified by adding or subtracting an
- integral constant expression.
-
- If you do not explicitly initialize an extern variable, its initial value is
- zero of the appropriate type. Initialization of an extern object is completed
- by the time the program starts running.
-
- extern objects have static storage duration. Memory is allocated for extern
- objects before the main function begins running. When the program finishes
- running, the storage is freed.
-
- Examples of extern Storage Class
-
- Related Information
-
- Storage Class Specifiers
- File Scope Data Declarations
- Function Definitions
- Function Declarator
- Constant Expressions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of extern Storage Class ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program shows the linkage of extern objects and functions. The
- extern object total is declared on line 12 of File 1 and on line 11 of File 2.
- The definition of the external object total appears in File 3. The extern
- function tally is defined in File 2. The function tally can be in the same file
- as main or in a different file. Because main precedes these definitions and
- main uses both total and tally, main declares tally on line 11 and total on
- line 12.
-
- File 1
-
-
- ************************************************************************/
-
- 1 /**************************************************************
- 2 ** The program receives the price of an item, adds the **
- 3 ** tax, and prints the total cost of the item. **
- 5 **************************************************************/
- 6
- 7 #include <stdio.h>
- 8
- 9 int main(void)
- 10 { /* begin main */
- 11 void tally(void); /* declaration of function tally */
- 12 extern float total; /* first declaration of total */
- 13
- 14 printf("Enter the purchase amount: \n");
- 15 tally();
- 16 printf("\nWith tax, the total is: %.2f\n", total);
- 17
- 18 return(0);
- 19 } /* end main */
-
- /************************************************************************
- *
-
- File 2
-
- *
- ************************************************************************/
-
- 1 /**************************************************************
- 2 ** This file defines the function tally **
- 3 **************************************************************/
- 4 #include <stdio.h>
- 6 #define tax_rate 0.05
- 7
- 8 void tally(void)
- 9 { /* begin tally */
- 10 float tax;
- 11 extern float total; /* second declaration of total */
- 12
- 13 scanf("%f", &total);
- 14 tax = tax_rate * total;
- 15 total += tax;
- 16 } /* end tally */
-
- /************************************************************************
- *
-
- File 3
-
- *
- ************************************************************************/
-
- 1 float total;
-
- /************************************************************************
- *
-
- When this program is run, interaction with it could produce:
-
- Output Enter the purchase amount:
-
- Input 99.95
-
- Output With tax, the total is: 104.95
-
- The following program shows extern variables used by two functions. Because
- both functions main and sort can access and change the values of the extern
- variables string and length, main does not have to pass parameters to sort.
-
- *
- ************************************************************************/
-
- /*****************************************************************
- ** Sorted string program -- this example shows extern **
- ** used by two functions **
- *****************************************************************/
-
- #include <stdio.h>
- #include <string.h>
-
- char string[75];
- int length;
-
- int main(void)
- {
- void sort(void);
-
- printf("Enter letters:\n");
- scanf("%s", string);
- length = strlen(string);
- sort();
- printf("The sorted string is: %s\n", string);
-
- return(0);
- }
-
- void sort(void)
- {
- int gap, i, j, temp;
-
- for (gap = length / 2; gap > 0; gap /= 2)
- for (i = gap; i < length; i++)
- for (j = i - gap;
- j >= 0 && string[j] > string[j + gap];
- j -= gap)
- {
- temp = string[j];
- string[j] = string[j + gap];
- string[j + gap] = temp;
- }
- }
-
- /************************************************************************
- *
-
- When this program is run, interaction with it could produce:
-
- Output Enter letters:
-
- Input zyfab
-
- Output The sorted string is: abfyz
-
- The following program shows a static variable var1, which is defined at file
- scope and then declared with the storage class specifier extern. The second
- declaration refers to the first definition of var1 and so it has internal
- linkage.
-
- static int var1;
- .
- .
- .
- extern int var1;
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.4.3. register Storage Class Specifier ΓòÉΓòÉΓòÉ
-
- The register storage class specifier indicates to the compiler that a heavily
- used variable (such as a loop control variable) within a block scope data
- definition or a parameter declaration should be allocated a register to
- minimize access time.
-
- It is equivalent to the auto storage class except that the compiler places the
- object, if possible, into a machine register for faster access.
-
- Note: Because the VisualAge for C++ compiler optimizes register use, it
- ignores the register keyword.
-
- Most heavily used entities are generated by the compiler itself; therefore,
- register variables are given no special priority for placement in machine
- registers. The register storage class keyword is required in a data definition
- and in a parameter declaration that describes an object having the register
- storage class. An object having the register storage class specifier must be
- defined within a block or declared as a parameter to a function.
-
- You can initialize any register object except parameters. If you do not
- initialize an automatic object, its value is indeterminate. If you provide an
- initial value, the expression representing the initial value can be any valid C
- or C++ expression. For structure and union members, the initial value must be a
- valid constant expression if an initializer list is used. The object is then
- set to that initial value each time the program block that contains the
- object's definition is entered.
-
- Objects with the register storage class specifier have automatic storage
- duration. Each time a block is entered, storage for register objects defined in
- that block are made available. When the block is exited, the objects are no
- longer available for use.
-
- If a register object is defined within a function that is recursively invoked,
- the memory is allocated for the variable at each invocation of the block.
-
- The register storage class specifier indicates that the object is heavily used
- and indicates to the compiler that the value of the object should reside in a
- machine register. Because of the limited size and number of registers available
- on most systems, few variables can actually be put in registers.
-
- If the compiler does not allocate a machine register for a register object, the
- object is treated as having the storage class specifier auto.
-
- Using register definitions for variables that are heavily used may make your
- object files smaller and make them run faster. In object code, a reference to a
- register can require less code and time than a reference to memory.
-
- Restrictions
-
- You cannot use the register storage class specifier in file scope data
- declarations.
-
- C++ Note:
-
- In C programs, you cannot apply the address (&) operator to register variables.
- However, C++ lets you take the address of an object with the register storage
- class. For example:
-
- register i;
- int* b = &i; // valid in C++, but not in C
-
- Related Information
-
- Storage Class Specifiers
- Block Scope Data Declarations
- auto Storage Class Specifier
- Address &
-
-
- ΓòÉΓòÉΓòÉ 4.4.4. static Storage Class Specifier ΓòÉΓòÉΓòÉ
-
- The static storage class specifier lets you define objects with static storage
- duration and internal linkage, or to define functions with internal linkage.
-
- An object having the static storage class specifier can be defined within a
- block or at file scope. If the definition occurs within a block, the object has
- no linkage. If the definition occurs at file scope, the object has internal
- linkage.
-
- You can initialize any static object with a constant expression or an
- expression that reduces to the address of a previously declared extern or
- static object, possibly modified by a constant expression. If you do not
- provide an initial value, the object receives the value of zero of the
- appropriate type. Initializing a C static data pointer to the address of an
- imported data object causes a compilation error. Such an initialization is
- permitted in C++.
-
- Storage is allocated at compile time for static variables that are initialized.
- Uninitialized static variables are mapped at compile time and initialized to 0
- (zero) at load time. This storage is freed when the program finishes running.
- Beyond this, the language does not define the order of initialization of
- objects from different files.
-
- Use static variables to declare objects that retain their value from one
- execution of a block to the next execution of that block. The static storage
- class specifier keeps the variable from being reinitialized each time the block
- where the variable is defined runs. For example:
-
- static float rate = 10.5;
-
- Initialization of a static array is performed only once at compile time. The
- following examples show the initialization of an array of characters and an
- array of integers:
-
- static char message[] = "startup completed";
- static int integers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
-
- The static storage class specifier causes the variable to be visible only in
- the file where it is declared. Files, therefore, cannot access file scope
- static variables declared in other files.
-
- C++ Note:
-
- If a local static variable is a class object with constructors and destructors,
- the object is constructed when control passes through its definition for the
- first time. If a local class object is created by a constructor, its destructor
- is called immediately before or as part of the calls of the atexit function.
-
- You cannot declare a static function at block scope.
-
- Examples of static Storage Class
-
- Related Information
-
- Storage Class Specifiers
- Block Scope Data Declarations
- File Scope Data Declarations
- Function Definitions
- Function Declarator
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of static Storage Class ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program shows the linkage of static identifiers at file scope.
- This program uses two different external static identifiers named stat_var. The
- first definition occurs in file 1. The second definition occurs in file 2. The
- main function references the object defined in file 1. The var_print function
- references the object defined in file 2:
-
- File 1
-
- *
- ************************************************************************/
-
- /************************************************************************
- ** Program to illustrate file scope static variables **
- ************************************************************************/
-
- #include <stdio.h>
-
- extern void var_print(void);
- static stat_var = 1;
-
- int main(void)
- {
- printf("file1 stat_var = %d\n", stat_var);
- var_print();
- printf("FILE1 stat_var = %d\n", stat_var);
-
- return(0);
- }
-
- /************************************************************************
- *
-
- File 2
-
- *
- ************************************************************************/
-
- /************************************************************************
- ** This file contains the second definition of stat_var **
- ************************************************************************/
-
- #include <stdio.h>
-
- static int stat_var = 2;
-
- void var_print(void)
- {
- printf("file2 stat_var = %d\n", stat_var);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- file1 stat_var = 1
- file2 stat_var = 2
- FILE1 stat_var = 1
-
- The following program shows the linkage of static identifiers with block scope.
- The function test defines the static variable stat_var, which retains its
- storage throughout the program, even though test is the only function that can
- refer to stat_var.
-
- *
- ************************************************************************/
-
- /************************************************************************
- ** Program to illustrate block scope static variables **
- ************************************************************************/
-
- #include <stdio.h>
-
- int main(void)
- {
- void test(void);
- int counter;
- for (counter = 1; counter <= 4; ++counter)
- test();
-
- return(0);
- }
-
- void test(void)
- {
- static int stat_var = 0;
- auto int auto_var = 0;
- stat_var++;
- auto_var++;
- printf("stat_var = %d auto_var = %d\n", stat_var, auto_var);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- stat_var = 1 auto_var = 1
- stat_var = 2 auto_var = 1
- stat_var = 3 auto_var = 1
- stat_var = 4 auto_var = 1
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.4.5. typedef ΓòÉΓòÉΓòÉ
-
- A typedef declaration lets you define your own identifiers that can be used in
- place of type specifiers such as int, float, and double. A typedef declaration
- does not reserve storage. The names you define using typedef are not new data
- types. They are synonyms for the data types or combinations of data types they
- represent.
-
- Syntax of a typedef Declaration
-
- When an object is defined using a typedef identifier, the properties of the
- defined object are exactly the same as if the object were defined by explicitly
- listing the data type associated with the identifier.
-
- C++ Note:
-
- A C++ class defined in a typedef without being named is given a dummy name and
- the typedef name for linkage. Such a class cannot have constructors or
- destructors. For example:
-
- typedef class {
- Trees();
- } Trees;
-
- Here the function Trees() is an ordinary member function of a class whose type
- name is unspecified. In the above example, Trees is an alias for the unnamed
- class, not the class type name itself, so Trees() cannot be a constructor for
- that class.
-
- Duplicate typedefs are permitted. For example,
-
- typedef int zip;
- typedef int zip;
- typedef zip zip;
-
- are allowed within a given scope.
-
- The following statements declare LENGTH as a synonym for int and then use this
- typedef to declare length, width, and height as integral variables:
-
- typedef int LENGTH;
- LENGTH length, width, height;
-
- The following declarations are equivalent to the above declaration:
-
- int length, width, height;
-
- Similarly, typedef can be used to define a class type (structure, union, or C++
- class). For example:
-
- typedef struct {
- int scruples;
- int drams;
- int grains;
- } WEIGHT;
-
- The structure WEIGHT can then be used in the following declarations:
-
- WEIGHT chicken, cow, horse, whale;
-
- Related Information
-
- Characters
- Floating-Point Variables
- Integer Variables
- Enumerations
- Pointers
- void Type
- Arrays
- Structures
- Unions
- C++ Classes
- Constructors and Destructors Overview
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a typedef Declaration ΓòÉΓòÉΓòÉ
-
- The syntax of a typedef declaration is:
-
- >>ΓöÇΓöÇtypedefΓöÇΓöÇtype_specifierΓöÇΓöÇidentifierΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ 4.5. Type Specifiers ΓòÉΓòÉΓòÉ
-
- Type specifiers indicate the type of the object or function being declared. The
- fundamental data types are:
-
- Characters
- Floating-Point Variables
- Integer Variables
- Enumerations
- void Type
-
- From these types, you can derive:
-
- Pointers
- Arrays
- Structures
- Unions
- Functions
-
- The integral types are char, wchar_t (C++ only), and int of all sizes.
- Floating-point numbers can have types float, double, or long double. Integral
- and floating-point types are collectively called arithmetic types. In C++
- only, you can also derive the following:
-
- References
- Classes
- Pointers to Members
-
- In C++, enumerations are not an integral type, but they can be subject to
- integral promotion, as described in Integral Promotions.
-
- You can give names to both fundamental and derived types by using the typedef
- specifier.
-
-
- ΓòÉΓòÉΓòÉ 4.5.1. Characters ΓòÉΓòÉΓòÉ
-
- There are three character data types: char, signed char, and unsigned char.
- These three data types are not compatible.
-
- The character data types provide enough storage to hold any member of the
- character set used at run time. The amount of storage allocated for a char is
- implementation-dependent. The VisualAge for C++ compiler represents a character
- by 8 bits, as defined in the CHAR_BIT macro in the <limits.h> header.
-
- The default character type behaves like an unsigned char. To change this
- default, use #pragma chars or the /J compiler option.
-
- If it does not matter whether a char data object is signed or unsigned, you can
- declare the object as having the data type char; otherwise, explicitly declare
- signed char or unsigned char. When a char (signed or unsigned) is widened to an
- int, its value is preserved.
-
- To declare a data object having a character type, use a char type specifier.
-
- The declarator for a simple character declaration is an identifier. You can
- initialize a simple character with a character constant or with an expression
- that evaluates to an integer.
-
- Use the char specifier in variable definitions to define such variables as:
- arrays of characters, pointers to characters, and arrays of pointers to
- characters. Use signed char or unsigned char to declare numeric variables that
- occupy a single byte.
-
- C++ Note: For the purposes of distinguishing overloaded functions, a C++ char
- is a distinct type from signed char and unsigned char.
-
- Examples of Character Data Types
-
- Related Information
-
- Arrays
- Pointers
- Character Constants
- Assignment Expressions
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Character Data Types ΓòÉΓòÉΓòÉ
-
- The following example defines the identifier end_of_string as a constant object
- of type char having the initial value \0 (the null character):
-
- const char end_of_string = '\0';
-
- The following example defines the unsigned char variable switches as having the
- initial value 3:
-
- unsigned char switches = 3;
-
- The following example defines string_pointer as a pointer to a character:
-
- char *string_pointer;
-
- The following example defines name as a pointer to a character. After
- initialization, name points to the first letter in the character string
- "Johnny":
-
- char *name = "Johnny";
-
- The following example defines a one-dimensional array of pointers to
- characters. The array has three elements. Initially they are a pointer to the
- string "Venus", a pointer to "Jupiter", and a pointer to "Saturn":
-
- static char *planets[ ] = { "Venus", "Jupiter", "Saturn" };
-
-
- ΓòÉΓòÉΓòÉ 4.5.2. Floating-Point Variables ΓòÉΓòÉΓòÉ
-
- There are three types of floating-point variables: float, double, and long
- double.
-
- The amount of storage allocated for a float, a double, or a long double is
- implementation-dependent. On all compilers, the storage size of a float
- variable is less than or equal to the storage size of a double variable.
-
- The VisualAge for C++ compiler allocates the following storage for
- floating-point types:
-
- 4 bytes for a float with 32 bits of precision
- 8 bytes for a double with 64 bits of precision
- 16 bytes for a long double, with 80 bits of precision
-
- For more information about compiler options and the VisualAge for C++
- implementation of floating-point types, see the IBM VisualAge for C++ for
- Windows User's Guide.
-
- To declare a data object having a floating-point type, use the float
- specifier.
-
- The declarator for a simple floating-point declaration is an identifier.
- Initialize a simple floating-point variable with a float constant or with a
- variable or expression that evaluates to an integer or floating-point number.
- The storage class of a variable determines how you initialize the variable.
-
- Examples of Floating-Point Data Types
-
- Related Information
-
- Floating-Point Constants
- <float.h>
- Assignment Expressions
- Integer Variables
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Floating-Point Data Types ΓòÉΓòÉΓòÉ
-
- The following example defines the identifier pi as an object of type double:
-
- double pi;
-
- The following example defines the float variable real_number with the initial
- value 100.55:
-
- static float real_number = 100.55f;
-
- The following example defines the float variable float_var with the initial
- value 0.0143:
-
- float float_var = 1.43e-2f;
-
- The following example declares the long double variable maximum:
-
- extern long double maximum;
-
- The following example defines the array table with 20 elements of type double:
-
- double table[20];
-
-
- ΓòÉΓòÉΓòÉ 4.5.3. Integer Variables ΓòÉΓòÉΓòÉ
-
- Integer variables fall into the following categories:
-
- short int or short or signed short int or signed short
- signed int or int
- long int or long or signed long int
- long long int or long long or signed long long int or signed long
- unsigned short int or unsigned short
- unsigned or unsigned int
- unsigned long int or unsigned long
- unsigned long long int or unsigned long long
-
- The default integer type for a bit field is unsigned.
-
- Use the bitfields=signed option to change this default.
-
- The amount of storage allocated for integer data is implementation-dependent.
-
- The VisualAge for C++ compiler allocates the following storage for integer
- types:
-
- 2 bytes for a short
- 4 bytes for an int
- 4 bytes for a long
- 8 bytes for a long long
-
- Note: The long long integer is not a standard C or C++ data type. It might be
- needed for some Windows system programming, but it may not be portable to
- other systems.
-
- For more information about the VisualAge for C++ implementation of integer
- types, see the IBM VisualAge for C++ for Windows User's Guide.
-
- The unsigned prefix indicates that the object is a nonnegative integer. Each
- unsigned type provides the same size storage as its signed equivalent. For
- example, int reserves the same storage as unsigned int. Because a signed type
- reserves a sign bit, an unsigned type can hold a larger positive integer than
- the equivalent signed type.
-
- To declare a data object having an integer data type, use an int type
- specifier.
-
- The declarator for a simple integer definition or declaration is an
- identifier. You can initialize a simple integer definition with an integer
- constant or with an expression that evaluates to a value that can be assigned
- to an integer. The storage class of a variable determines how you can
- initialize the variable.
-
- C++ Note: When the arguments in overloaded functions and overloaded operators
- are integer types, two integer types that both come from the same group are
- not treated as distinct types. For example, you cannot overload an int
- argument against a signed int argument. Overloading and argument matching is
- described in C++ Overloading.
-
- Examples of Integer Data Types
-
- Related Information
-
- Integer Constants
- Decimal Constants
- Octal Constants
- Hexadecimal Constants
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Integer Data Types ΓòÉΓòÉΓòÉ
-
- The following example defines the short int variable flag:
-
- short int flag;
-
- The following example defines the int variable result:
-
- int result;
-
- The following example defines the unsigned long int variable ss_number as
- having the initial value 438888834:
-
- unsigned long ss_number = 438888834ul;
-
- The following example defines the identifier sum as an object of type int. The
- initial value of sum is the result of the expression a + b:
-
- extern int a, b;
- auto sum = a + b;
-
-
- ΓòÉΓòÉΓòÉ 4.5.4. Enumerations ΓòÉΓòÉΓòÉ
-
- An enumeration data type represents a set of values that you declare. You can
- define an enumeration data type and all variables that have that enumeration
- type in one statement, or you can declare an enumeration type separately from
- the definition of variables of that type. The identifier associated with the
- data type (not an object) is called an enumeration tag.
-
- C++ Note: In C, an enumeration has an implementation-defined integral type.
- This restriction does not apply to C++. In C++, an enumeration has a distinct
- type that does not have to be integral.
-
- An enumeration type declaration contains the enum keyword followed by an
- optional identifier (the enumeration tag) and a brace-enclosed list of
- enumerators. Commas separate each enumerator in the enumerator list. In
- extended mode, a trailing comma is permitted at the end of the enumerator list.
-
- Syntax of an Enumeration
-
- The keyword enum, followed by the identifier, names the data type (like the tag
- on a struct data type). The list of enumerators provides the data type with a
- set of values.
-
- C++ Note: In C, each enumerator represents an integer value. In C++, each
- enumerator represents a value that can be converted to an integral value.
-
- To conserve space, enumerations may be stored in spaces smaller than that of an
- int. By default, the type of the enum variable is the size of the smallest
- integral type that can contain all enumerator values. You can change the
- default using the /Su option, described in the IBM VisualAge for C++ for
- Windows User's Guide.
-
- When you define an enumeration data type, you specify a set of identifiers that
- the data type represents. Each identifier in this set is an enumeration
- constant.
-
- The value of the constant is determined in the following way:
-
- 1. An equal sign (=) and a constant expression after the enumeration
- constant gives an explicit value to the constant. The identifier
- represents the value of the constant expression.
-
- 2. If no explicit value is assigned, the leftmost constant in the list
- receives the value zero (0).
-
- 3. Identifiers with no explicitly assigned values receive the integer value
- that is one greater than the value represented by the previous
- identifier.
-
- In C, enumeration constants have type int.
-
- In C++, each enumeration constant has a value that can be promoted to a signed
- or unsigned integer value and a distinct type that does not have to be
- integral. Use an enumeration constant anywhere an integer constant is allowed,
- or for C++, anywhere a value of the enumeration type is allowed.
-
- Each enumeration constant must be unique within the scope in which the
- enumeration is defined. It is possible to associate the same integer with two
- different enumeration constants.
-
- Additional information is provided on:
-
- Defining Enumeration Variables
- Defining Enumeration Types and Objects
- Example Program Using Enumeration Types
-
- Examples of Enumeration Types and Constants
-
- Related Information
-
- Constant Expressions
- Identifiers
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Enumeration Syntax ΓòÉΓòÉΓòÉ
-
- An enumeration type declaration has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇenumΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇenumeratorΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓöÇ;ΓöÇΓöÇ><
- ΓööΓöÇidentifierΓöÇΓöÿ
-
- An enumerator has the form:
-
- >>ΓöÇΓöÇidentifierΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ=ΓöÇΓöÇintegral_constant_expressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Enumeration Types and Constants ΓòÉΓòÉΓòÉ
-
- In the following example, the declarations of average on line 4 and of poor on
- line 5 cause compiler error messages:
-
- 1 func()
- 2 {
- 3 enum score { poor, average, good };
- 4 enum rating { below, average, above };
- 5 int poor;
- 6 }
-
- The following data type declarations list oats, wheat, barley, corn, and rice
- as enumeration constants. The number under each constant shows the integer
- value.
-
- enum grain { oats, wheat, barley, corn, rice };
- /* 0 1 2 3 4 */
-
- enum grain { oats=1, wheat, barley, corn, rice };
- /* 1 2 3 4 5 */
-
- enum grain { oats, wheat=10, barley, corn=20, rice };
- /* 0 10 11 20 21 */
-
- It is possible to associate the same integer with two different enumeration
- constants. For example, the following definition is valid. The identifiers
- suspend and hold have the same integer value.
-
- enum status { run, clear=5, suspend, resume, hold=6 };
- /* 0 5 6 7 6 */
-
- The following example is a different declaration of the enumeration tag status:
-
- enum status { run, create, clear=5, suspend };
- /* 0 1 5 6 */
-
-
- ΓòÉΓòÉΓòÉ 4.5.4.1. Defining Enumeration Variables ΓòÉΓòÉΓòÉ
-
- An enumeration variable definition contains an optional storage class
- specifier, a type specifier, a declarator, and an optional initializer. The
- type specifier contains the keyword enum followed by the name of the
- enumeration data type. You must declare the enumeration data type before you
- can define a variable having that type.
-
- The initializer for an enumeration variable contains the = symbol followed by
- an expression.
-
- In C, the initializer expression must evaluate to an int value. In C++, the
- initializer must be have the same type as the associated enumeration type.
-
- The first line of the following example declares the enumeration tag grain. The
- second line defines the variable g_food and gives g_food the initial value of
- barley (2).
-
- enum grain { oats, wheat, barley, corn, rice };
- enum grain g_food = barley;
-
- In C, the type specifier enum grain indicates that the value of g_food is a
- member of the enumerated data type grain. In C++, the value of g_food has the
- enumerated data type grain.
-
- C++ also makes the enum keyword optional in an initialization expression like
- the one in the second line of the preceding example. For example, both of the
- following statements are valid C++ code:
-
- enum grain g_food = barley;
- grain cob_food = corn;
-
-
- ΓòÉΓòÉΓòÉ 4.5.4.2. Defining Enumeration Types and Objects ΓòÉΓòÉΓòÉ
-
- You can define a type and a variable in one statement by using a declarator and
- an optional initializer after the type definition. To specify a storage class
- specifier for the variable, you must put the storage class specifier at the
- beginning of the declaration. For example:
-
- register enum score { poor=1, average, good } rating = good;
-
- C++ also lets you put the storage class immediately before the declarator. For
- example:
-
- enum score { poor=1, average, good } register rating = good;
-
- Either of these examples is equivalent to the following two declarations:
-
- enum score { poor=1, average, good };
- register enum score rating = good;
-
- Both examples define the enumeration data type score and the variable rating.
- rating has the storage class specifier register, the data type enum score, and
- the initial value good.
-
- Combining a data type definition with the definitions of all variables having
- that data type lets you leave the data type unnamed. For example:
-
- enum { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday,
- Saturday } weekday;
-
- defines the variable weekday, which can be assigned any of the specified
- enumeration constants.
-
-
- ΓòÉΓòÉΓòÉ 4.5.4.3. Example Program Using Enumerations ΓòÉΓòÉΓòÉ
-
- /**********************************************************************************
- *
- The following program receives an integer as input. The output is a sentence
- that gives the French name for the weekday that is associated with the integer.
- If the integer is not associated with a weekday, the program prints "C'est le
- mauvais jour."
-
- *
- ************************************************************************/
-
- /**
- ** Example program using enumerations
- **/
-
- #include <stdio.h>
-
- enum days {
- Monday=1, Tuesday, Wednesday,
- Thursday, Friday, Saturday, Sunday
- } weekday;
-
- void french(enum days);
-
- int main(void)
- {
- int num;
-
- printf("Enter an integer for the day of the week. "
- "Mon=1,...,Sun=7\n");
- scanf("%d", &num);
- weekday=num;
- french(weekday);
- return(0);
- }
- void french(enum days weekday)
- {
- switch (weekday)
- {
- case Monday:
- printf("Le jour de la semaine est lundi.\n");
- break;
- case Tuesday:
- printf("Le jour de la semaine est mardi.\n");
- break;
- case Wednesday:
- printf("Le jour de la semaine est mercredi.\n");
- break;
- case Thursday:
- printf("Le jour de la semaine est jeudi.\n");
- break;
- case Friday:
- printf("Le jour de la semaine est vendredi.\n");
- break;
- case Saturday:
- printf("Le jour de la semaine est samedi.\n");
- break;
- case Sunday:
- printf("Le jour de la semaine est dimanche.\n");
- break;
- default:
- printf("C'est le mauvais jour.\n");
- }
- }
-
-
- ΓòÉΓòÉΓòÉ 4.5.5. Pointers ΓòÉΓòÉΓòÉ
-
- A pointer type variable holds the address of a data object or a function. A
- pointer can refer to an object of any one data type except to a bit field or a
- reference. Additionally, in C, a pointer cannot point to an object with the
- register storage class. Some common uses for pointers are:
-
- To access dynamic data structures such as linked lists, trees, and
- queues.
- To access elements of an array or members of a structure or C++ class.
- To access an array of characters as a string.
- To pass the address of a variable to a function. (In C++, you can also
- use a reference to do this.) By referencing a variable through its
- address, a function can change the contents of that variable. Calling
- Functions and Passing Arguments describes passing arguments by reference.
-
- The following example declares pcoat as a pointer to an object having type
- long:
-
- extern long *pcoat;
-
- If the keyword volatile appears before the *, the declarator describes a
- pointer to a volatile object. If the keyword volatile comes between the * and
- the identifier, the declarator describes a volatile pointer. The keyword const
- operates in the same manner as the volatile keyword.
-
- Examples of Pointer Declarations
-
- Additional information is provided on:
-
- Assigning Pointers
- Initializing Pointers
- Restrictions on Pointers
- Using Pointers
- Pointer Arithmetic
- Example Program Using Pointers
-
- Related Information
-
- Address &
- Indirection *
- __unaligned Type Qualifier
- References
- Declarators
- volatile and const Qualifiers
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Pointer Declarations ΓòÉΓòÉΓòÉ
-
- In the following example, pvolt is a constant pointer to an object having type
- short:
-
- short * const pvolt;
-
- The following example declares pnut as a pointer to an int object having the
- volatile qualifier:
-
- extern int volatile *pnut;
-
- The following example defines psoup as a volatile pointer to an object having
- type float:
-
- float * volatile psoup;
-
- The following example defines pfowl as a pointer to an enumeration object of
- type bird:
-
- enum bird *pfowl;
-
- The next example declares pvish as a pointer to a function that takes no
- parameters and returns a char object:
-
- char (*pvish)(void);
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.1. Assigning Pointers ΓòÉΓòÉΓòÉ
-
- When you use pointers in an assignment operation, you must ensure that the
- types of the pointers in the operation are compatible.
-
- The following example shows compatible declarations for the assignment
- operation:
-
- float subtotal;
- float * sub_ptr;
- .
- .
- .
- sub_ptr = &subtotal;
- printf("The subtotal is %f\n", *sub_ptr);
-
- The next example shows incompatible declarations for the assignment operation:
-
- double league;
- int * minor;
- .
- .
- .
- minor = &league; /* error */
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.2. Initializing Pointers ΓòÉΓòÉΓòÉ
-
- The initializer is an = (equal sign) followed by the expression that represents
- the address that the pointer is to contain. The following example defines the
- variables time and speed as having type double and amount as having type
- pointer to a double. The pointer amount is initialized to point to total:
-
- double total, speed, *amount = &total;
-
- The compiler converts an unsubscripted array name to a pointer to the first
- element in the array. You can assign the address of the first element of an
- array to a pointer by specifying the name of the array. The following two sets
- of definitions are equivalent. Both define the pointer student and initialize
- student to the address of the first element in section:
-
- int section[80];
- int *student = section;
-
- is equivalent to:
-
- int section[80];
- int *student = §ion[0];
-
- You can assign the address of the first character in a string constant to a
- pointer by specifying the string constant in the initializer.
-
- The following example defines the pointer variable string and the string
- constant "abcd". The pointer string is initialized to point to the character a
- in the string "abcd".
-
- char *string = "abcd";
-
- The following example defines weekdays as an array of pointers to string
- constants. Each element points to a different string. The pointer weekdays[2],
- for example, points to the string "Tuesday".
-
- static char *weekdays[ ] =
- {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"
- };
-
- A pointer can also be initialized to NULL using any integer constant expression
- that evaluates to 0, for example char * a=0;. Such a pointer is a NULL pointer.
- It does not point to any object.
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.3. Restrictions on Pointers ΓòÉΓòÉΓòÉ
-
- You cannot use pointers to reference bit fields or objects having the register
- storage class specifier. Initializing a C static data pointer to the address of
- an imported data object causes a compilation error. Such an initialization is
- permitted in C++.
-
- A pointer to a packed structure or union is incompatible with a pointer to a
- corresponding nonpacked structure or union because packed and nonpacked objects
- have different memory layouts. As a result, comparisons and assignments between
- pointers to packed and nonpacked objects are not valid.
-
- You can, however, perform these assignments and comparisons with type casts. In
- the following example:
-
- int main(void)
- {
- _Packed struct ss *ps1;
- struct ss *ps2;
- .
- .
- .
- ps1 = (_Packed struct ss *)ps2;
- .
- .
- .
- }
-
- the cast operation lets you compare the two pointers, but you must be aware
- that ps1 still points to a nonpacked object.
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.4. Using Pointers ΓòÉΓòÉΓòÉ
-
- Two operators are commonly used in working with pointers, the address (&)
- operator and the indirection (*) operator. You can use the & operator to refer
- to the address of an object. For example, the following statement assigns the
- address of x to the variable p_to_x. The variable p_to_x has been defined as a
- pointer.
-
- int x, *p_to_x;
-
- p_to_x = &x;
-
- The * (indirection) operator lets you access the value of the object a pointer
- refers to. The following statement assigns to y the value of the object that
- p_to_x points to:
-
- float y, *p_to_x;
- .
- .
- .
- y = *p_to_x;
-
- The following statement assigns the value of y to the variable that *p_to_x
- references:
-
- char y ,
- *p_to_x,
- .
- .
- .
- *p_to_x = y;
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.5. Pointer Arithmetic ΓòÉΓòÉΓòÉ
-
- You can perform a limited number of arithmetic operations on pointers. These
- operations are:
-
- Increment and decrement
- Addition and subtraction
- Comparison
- Assignment
-
- The increment (++) operator increases the value of a pointer by the size of
- the data object the pointer refers to. For example, if the pointer refers to
- the second element in an array, the ++ makes the pointer refer to the third
- element in the array.
-
- The decrement (--) operator decreases the value of a pointer by the size of
- the data object the pointer refers to. For example, if the pointer refers to
- the second element in an array, the -- makes the pointer refer to the first
- element in the array.
-
- You can add a pointer to an integer, but you cannot add a pointer to a
- pointer.
-
- If the pointer p points to the first element in an array, the following
- expression causes the pointer to point to the third element in the same array:
-
- p = p + 2;
-
- If you have two pointers that point to the same array, you can subtract one
- pointer from the other. This operation yields the number of elements in the
- array that separate the two addresses that the pointers refer to.
-
- You can compare two pointers with the following operators: ==, !=, <, >, <=,
- and >=. See Expressions and Operators for more information on these operators.
-
- Pointer comparisons are defined only when the pointers point to elements of
- the same array. Pointer comparisons using the == and != operators can be
- performed even when the pointers point to elements of different arrays.
-
- You can assign to a pointer the address of a data object, the value of another
- compatible pointer or the NULL pointer.
-
-
- ΓòÉΓòÉΓòÉ 4.5.5.6. Example Program Using Pointers ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program contains pointer arrays:
-
- *
- ************************************************************************/
-
- /********************************************************************
- ** Program to search for the first occurrence of a specified **
- ** character string in an array of character strings. **
- ********************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define SIZE 20
- #define EXIT_FAILURE 999
-
- int main(void)
- {
- static char *names[ ] = { "Jim", "Amy", "Mark", "Sue", NULL };
- char * find_name(char **, char *);
- char new_name[SIZE], *name_pointer;
-
- printf("Enter name to be searched.\n");
- scanf("%s", new_name);
- name_pointer = find_name(names, new_name);
- printf("name %s%sfound\n", new_name,
- (name_pointer == NULL) ? " not " : " ");
- exit(EXIT_FAILURE);
- } /* End of main */
- /********************************************************************
- ** Function find_name. This function searches an array of **
- ** names to see if a given name already exists in the array. **
- ** It returns a pointer to the name or NULL if the name is **
- ** not found. **
- ** **
- ** char **arry is a pointer to arrays of pointers (existing names) **
- ** char *strng is a pointer to character array entered (new name) **
- ********************************************************************/
-
- char * find_name(char **arry, char *strng)
- {
- for (; *arry != NULL; arry++) /* for each name */
- {
- if (strcmp(*arry, strng) == 0) /* if strings match */
- return(*arry); /* found it! */
- }
- return(*arry); /* return the pointer */
- } /* End of find_name */
-
- /************************************************************************
- *
-
- Interaction with this program could produce the following sessions:
-
- Output Enter name to be searched.
-
- Input Mark
-
- Output name Mark found
-
- OR:
-
- Output Enter name to be searched.
-
- Input Deborah
-
- Output name Deborah not found
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.5.6. void Type ΓòÉΓòÉΓòÉ
-
- The void data type always represents an empty set of values. The only object
- that can be declared with the type specifier void is a pointer.
-
- When a function does not return a value, you should use void as the type
- specifier in the function definition and declaration. An argument list for a
- function taking no arguments is void.
-
- You cannot declare a variable of type void, but you can explicitly convert any
- expression to type void, but the resulting expression can only be used as one
- of the following:
-
- An expression statement
- The left operand of a comma expression
- The second or third operand in a conditional expression.
-
- Example of void Type
-
- Related Information
-
- Cast Expressions
- Type Specifiers
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of void Type ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- On line 7 of the following example, the function find_max is declared as having
- type void. Lines 15 through 26 contain the complete definition of find_max.
-
- Note: The use of the sizeof operator in line 13 is a standard method of
- determining the number of elements in an array.
-
- *
- ************************************************************************/
-
- 1 /**
- 2 ** Example of void type
- 3 **/
- 4 #include <stdio.h>
- 5
- 6 /* declaration of function find_max */
- 7 extern void find_max(int x[ ], int j);
- 8
- 9 int main(void)
- 10 {
- 11 static int numbers[ ] = { 99, 54, -102, 89 };
- 12
- 13 find_max(numbers, (sizeof(numbers) / sizeof(numbers[0])));
- 14
- 15 return(0);
- 16 }
- 17
- 18 void find_max(int x[ ], int j)
- 19 { /* begin definition of function find_max */
- 20 int i, temp = x[0];
- 21
- 22 for (i = 1; i < j; i++)
- 23 {
- 24 if (x[i] > temp)
- 25 temp = x[i];
- 26 }
- 27 printf("max number = %d\n", temp);
- 28 } /* end definition of function find_max */
-
-
- ΓòÉΓòÉΓòÉ 4.5.7. Arrays ΓòÉΓòÉΓòÉ
-
- An array is an ordered group of data objects. Each object is called an element.
- All elements within an array have the same data type.
-
- Use any type specifier in an array definition or declaration. Array elements
- can be of any data type, except function or, in C++, a reference. You can,
- however, declare an array of pointers to functions.
-
- The array declarator contains an identifier followed by an optional subscript
- declarator. An identifier preceded by an * (asterisk) is an array of pointers.
-
- Syntax of a Subscript Declarator
-
- The subscript declarator describes the number of dimensions in the array and
- the number of elements in each dimension. Each bracketed expression, or
- subscript, describes a different dimension and must be a constant expression.
-
- The following example defines a one-dimensional array that contains four
- elements having type char:
-
- char list[4];
-
- The first subscript of each dimension is 0. The array list contains the
- elements:
-
- list[0]
- list[1]
- list[2]
- list[3]
-
- The following example defines a two-dimensional array that contains six
- elements of type int:
-
- int roster[3][2];
-
- Multidimensional arrays are stored in row-major order. When elements are
- referred to in order of increasing storage location, the last subscript varies
- the fastest. For example, the elements of array roster are stored in the order:
-
- roster[0][0]
- roster[0][1]
- roster[1][0]
- roster[1][1]
- roster[2][0]
- roster[2][1]
-
- In storage, the elements of roster would be stored as:
-
-
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
-
- Γöé Γöé Γöé
- roster[0][0] roster[0][1] roster[1][0]
-
- You can leave the first (and only the first) set of subscript brackets empty in
-
- Array definitions that contain initializations
- extern declarations
- Parameter declarations.
-
- In array definitions that leave the first set of subscript brackets empty, the
- initializer determines the number of elements in the first dimension. In a
- one-dimensional array, the number of initialized elements becomes the total
- number of elements. In a multidimensional array, the initializer is compared
- to the subscript declarator to determine the number of elements in the first
- dimension.
-
- An unsubscripted array name (for example, region instead of region[4])
- represents a pointer whose value is the address of the first element of the
- array, provided the array has previously been declared. An unsubscripted array
- name with square brackets (for example, region[]) is allowed in the following
- contexts:
-
- In arrays declared at file scope
- In the argument list of a function declaration
-
- In declarations, only the first dimension can be left empty; you must specify
- the sizes of additional dimensions.
-
- In extended modes, they are also permitted in the following contexts:
-
- In union members
- As the last member of a structure
-
- See Zero-Extent Arrays in Structures and Unions for more information about
- using unsubscripted arrays in these contexts.
-
- Whenever an array is used in a context (such as a parameter) where it cannot
- be used as an array, the identifier is treated as a pointer. The two
- exceptions are when an array is used as an operand of the sizeof or the
- address (&) operator.
-
- Additional information is provided on:
-
- Initializing Arrays
- Example Programs Using Arrays
-
- Related Information
-
- Pointers
- Array Subscript [ ] (Array Element Specification)
- String Literals
- Declarators
- Initializers
- Implicit Type Conversions
- Implicit Type Conversions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Subscript Declarator Syntax ΓòÉΓòÉΓòÉ
-
- A subscript declarator has the form:
-
- >>ΓöÇΓöÇ[ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ]ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇconstant_expressionΓöÇΓöÿ Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇ[ΓöÇΓöÇconstant_expressionΓöÇΓöÇ]ΓöÇΓö┤ΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.5.7.1. Initializing Arrays ΓòÉΓòÉΓòÉ
-
- The initializer for an array contains the = symbol followed by a
- comma-separated list of constant expressions enclosed in braces ({ }). You do
- not need to initialize all elements in an array. Elements that are not
- initialized (in extern and static definitions only) receive the value 0 of the
- appropriate type.
-
- Note: Array initializations can be either fully braced (with braces around
- each dimension) or unbraced (with only one set of braces enclosing the entire
- set of initializers). Avoid placing braces around some dimensions and not
- around others.
- Initializing a one-dimensional character array
-
- Initialize a one-dimensional character array by specifying:
-
- A brace-enclosed comma-separated list of constants, each of which can be
- contained in a character
- A string constant. (Braces surrounding the constant are optional.)
-
- Initializing a string constant places the null character (\0) at the end of
- the string if there is room or if the array dimensions are not specified.
-
- Examples of Initialized Arrays
-
- The following show four different character array initializations:
-
- static char name1[] = { 'J', 'a', 'n' };
- static char name2[] = { "Jan" };
- static char name3[3] = "Jan";
- static char name4[4] = "Jan";
-
- These initializations create the following elements:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé ELEMENT Γöé VALUEΓöé ELEMENT Γöé VALUEΓöé ELEMENT Γöé VALUEΓöé ELEMENT Γöé VALUΓöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "name1[0]" Γöé "J" Γöé "name2[0]" Γöé "J" Γöé "name3[0]" Γöé "J" Γöé "name4[0]" Γöé "J" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "name1[1]" Γöé "a" Γöé "name2[1]" Γöé "a" Γöé "name3[1]" Γöé "a" Γöé "name4[1]" Γöé "a" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "name1[2]" Γöé "n" Γöé "name2[2]" Γöé "n" Γöé "name3[2]" Γöé "n" Γöé "name4[2]" Γöé "n" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Γöé Γöé "name2[3]" Γöé "\0" Γöé Γöé Γöé "name4[3]" Γöé "\0"Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Note that the NULL character is lost for name1[] and name3[3]. In C, a
- compiler warning is issued for name3[3]. In C++, the compiler issues a severe
- error for name3[3].
- Initializing a multidimensional array
-
- Initialize a multidimensional array by:
-
- Listing the values of all elements you want to initialize, in the order
- that the compiler assigns the values. The compiler assigns values by
- increasing the subscript of the last dimension fastest. This form of a
- multidimensional array initialization looks like a one-dimensional array
- initialization. The following definition completely initializes the
- array month_days:
-
- static month_days[2][12] =
- {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
- 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
-
- Using braces to group the values of the elements you want initialized.
- You can put braces around each element, or around any nesting level of
- elements. The following definition contains two elements in the first
- dimension. (You can consider these elements as rows.) The initialization
- contains braces around each of these two elements:
-
- static int month_days[2][12] =
- {
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
- };
-
- Using use nested braces to initialize dimensions and elements in a
- dimension selectively.
-
- You cannot have more initializers than the number of elements in the array.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Initialized Arrays ΓòÉΓòÉΓòÉ
-
- The following definition shows a completely initialized one-dimensional array:
-
- static int number[3] = { 5, 7, 2 };
-
- The array number contains the following values:
-
- Element Value
- number[0] 5
- number[1] 7
- number[2] 2
-
- The following definition shows a partially initialized one-dimensional array:
-
- static int number1[3] = { 5, 7 };
-
- The values of number1 are:
-
- Element Value
- number1[0] 5
- number1[1] 7
- number1[2] 0
-
- Instead of an expression in the subscript declarator defining the number of
- elements, the following one-dimensional array definition defines one element
- for each initializer specified:
-
- static int item[ ] = { 1, 2, 3, 4, 5 };
-
- The compiler gives item the five initialized elements:
-
- Element Value
- item[0] 1
- item[1] 2
- item[2] 3
- item[3] 4
- item[4] 5
-
- The following definitions show character array initializations:
-
- static char name1[ ] = { 'J', 'a', 'n' };
- static char name2[ ] = { "Jan" };
- static char name3[4] = "Jan";
-
- These definitions create the following elements:
-
- Element Value
- name1[0] J
- name1[1] a
- name1[2] n
- name2[0] J
- name2[1] a
- name2[2] n
- name2[3] \0
- name3[0] J
- name3[1] a
- name3[2] n
-
- The following definition explicitly initializes six elements in a 12-element
- array:
-
- static int matrix[3][4] =
- {
- {1, 2},
- {3, 4},
- {5, 6}
- };
-
- The initial values of matrix are:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé ELEMENT Γöé VALUE Γöé ELEMENT Γöé VALUE Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[0][0]" Γöé "1" Γöé "matrix[1][2]" Γöé "0" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[0][1]" Γöé "2" Γöé "matrix[1][3]" Γöé "0" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[0][2]" Γöé "0" Γöé "matrix[2][0]" Γöé "5" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[0][3]" Γöé "0" Γöé "matrix[2][1]" Γöé "6" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[1][0]" Γöé "3" Γöé "matrix[2][2]" Γöé "0" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "matrix[1][1]" Γöé "4" Γöé "matrix[2][3]" Γöé "0" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.5.7.2. Zero-Extent Arrays in Structures and Unions ΓòÉΓòÉΓòÉ
-
- Zero-extent arrays are permitted in structures and unions under extended mode.
-
- For example, Struct_A contains the zero-extent array char arr_a[0], and
- Struct_B contains the zero-extent array char arr_b[].
-
- struct Struct_A {
- int i;
- char arr_a[0];
- } a;
-
- struct Struct_B {
- int k;
- char arr_b[];
- } a;
-
- Both char arr_a[0]; and char arr_b[]; are implicitly viewed by the compiler as
- if declared as arrays with one element:
-
- struct Struct_A {
- int i;
- char arr_a[1];
- } a;
-
- struct Struct_B {
- int k;
- char arr_b[1];
- } b;
-
- The zero-sized array can be any member of a union. Zero-sized arrays are only
- allowed as the last member of a structure.
-
- The sizeof operator assumes 1 for the zero-sized array.
-
- Structures containing zero-sized arrays can be nested within other structures
- as long as no additional members are subsequently declared in any enclosing
- structures. For example, the following declaration causes an error:
-
- struct Struct_S {
- int i;
- char arr_s[];
- };
-
- struct Struct_T {
- float f;
- struct Struct_S;
- int k; // Error - addtional structure member following a
- // struct containing a zero-sized array
- } t;
-
- Note:
-
- 1. In C++, the zero-sized array must be non-static.
-
- 2. In a class definition, the zero-sized array must be the last non-static
- data member. Members such as functions, static data members, and typedefs
- are allowed after the zero-sized array.
-
- 3. A class containing a zero-sized array cannot be used as a base class.
-
-
- ΓòÉΓòÉΓòÉ 4.5.7.3. Example Programs Using Arrays ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program defines a floating-point array called prices.
-
- The first for statement prints the values of the elements of prices. The second
- for statement adds five percent to the value of each element of prices, and
- assigns the result to total, and prints the value of total.
-
- *
- ************************************************************************/
-
- /**
- ** Example of one-dimensional arrays
- **/
-
- #include <stdio.h>
- #define ARR_SIZE 5
-
- int main(void)
- {
- static float const prices[ARR_SIZE] = { 1.41, 1.50, 3.75, 5.00, .86 };
- auto float total;
- int i;
-
- for (i = 0; i < ARR_SIZE; i++)
- {
- printf("price = $%.2f\n", prices[i]);
- }
-
- printf("\n");
-
- for (i = 0; i < ARR_SIZE; i++)
- {
- total = prices[i] * 1.05;
-
- printf("total = $%.2f\n", total);
- }
-
- return(0);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- price = $1.41
- price = $1.50
- price = $3.75
- price = $5.00
- price = $0.86
-
- total = $1.48
- total = $1.57
- total = $3.94
- total = $5.25
- total = $0.90
-
- The following program defines the multidimensional array salary_tbl. A for loop
- prints the values of salary_tbl.
-
- *
- ************************************************************************/
-
- /**
- ** Example of a multidimensional array
- **/
-
- #include <stdio.h>
- #define ROW_SIZE 3
- #define COLUMN_SIZE 5
-
- int main(void)
- {
- static int salary_tbl[ROW_SIZE][COLUMN_SIZE] =
- {
- { 500, 550, 600, 650, 700 },
- { 600, 670, 740, 810, 880 },
- { 740, 840, 940, 1040, 1140 }
- };
- int grade , step;
-
- for (grade = 0; grade < ROW_SIZE; ++grade)
- for (step = 0; step < COLUMN_SIZE; ++step)
- {
- printf("salary_tbl[%d] [%d] = %d\n", grade, step,
- salary_tbl[grade] [step]);
- }
-
- return(0);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- salary_tbl[0] [0] = 500
- salary_tbl[0] [1] = 550
- salary_tbl[0] [2] = 600
- salary_tbl[0] [3] = 650
- salary_tbl[0] [4] = 700
- salary_tbl[1] [0] = 600
- salary_tbl[1] [1] = 670
- salary_tbl[1] [2] = 740
- salary_tbl[1] [3] = 810
- salary_tbl[1] [4] = 880
- salary_tbl[2] [0] = 740
- salary_tbl[2] [1] = 840
- salary_tbl[2] [2] = 940
- salary_tbl[2] [3] = 1040
- salary_tbl[2] [4] = 1140
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.5.8. Structures ΓòÉΓòÉΓòÉ
-
- A structure contains an ordered group of data objects. Unlike the elements of
- an array, the data objects within a structure can have varied data types. Each
- data object in a structure is a member or field.
-
- Use structures to group logically related objects. For example, to allocate
- storage for the components of one address, define a number of variables for the
- street name and number, the city, and so on. To allocate storage for more than
- one address, group the components of each address by defining a structure data
- type and as many variables as you need to have the structure data type.
-
- In the following example, lines 1 through 7 declare the structure tag address:
-
- 1 struct address {
- 2 int street_no;
- 3 char *street_name;
- 4 char *city;
- 5 char *prov;
- 6 char *postal_code;
- 7 };
- 8 struct address perm_address;
- 9 struct address temp_address;
- 10 struct address *p_perm_address = &perm_address;
-
- The variables perm_address and temp_address are instances of the structure data
- type address. Both contain the members described in the declaration of address.
- The pointer p_perm_address points to a structure of address and is initialized
- to point to perm_address.
-
- Refer to a member of a structure by specifying the structure variable name with
- the dot operator (.) or a pointer with the arrow operator (->) and the member
- name. For example, both of the following:
-
- perm_address.prov = "Ontario";
- p_perm_address -> prov = "Ontario";
-
- assign a pointer to the string "Ontario" to the pointer prov that is in the
- structure perm_address.
-
- All references to structures must be fully qualified. In the example, you
- cannot reference the fourth field by prov alone. You must reference this field
- by perm_address.prov.
-
- Structures with identical members but different names are not compatible and
- cannot be assigned to each other.
-
- Structures are not intended to conserve storage. If you need direct control of
- byte mapping, use pointers.
-
- Structure member references are described in Dot Operator . and Arrow
- Operator ->
-
- You cannot declare a structure with members of incomplete types.
-
- A structure type declaration describes the members that are part of the
- structure. It contains the struct keyword followed by an optional identifier
- (the structure tag) and a brace-enclosed list of members.
-
- Syntax of a Structure
-
- The keyword struct followed by the identifier (tag) names the data type. If you
- do not provide a tag name to the data type, you must put all variable
- definitions that refer to it within the declaration of the data type.
-
- The list of members provides the data type with a description of the values
- that can be stored in the structure.
-
- If a : (colon) and a constant expression follow the member declarator, the
- member represents a bit field. A member that does not represent a bit field can
- be of any data type and can have the volatile or const qualifier.
-
- Identifiers used as structure or member names can be redefined to represent
- different objects in the same scope without conflicting. You cannot use the
- name of a member more than once in a structure type, but you can use the same
- member name in another structure type that is defined within the same scope.
-
- You cannot declare a structure type that contains itself as a member, but you
- can declare a structure type that contains a pointer to itself as a member.
-
- A structure variable definition contains an optional storage class keyword, the
- struct keyword, a structure tag, a declarator, and an optional identifier. The
- structure tag indicates the data type of the structure variable.
-
- C++ Note: The keyword struct is optional in C++.
-
- You can declare structures having any storage class.
-
- Additional information is provided on:
-
- Initializing Structures
- Declaring Structure Types and Variables
- Declaring and Using Bit Fields in Structures
- Declaring a Packed Structure
- Example Program Using Structures
-
- Related Information
-
- Dot Operator .
- Arrow Operator ->
- _Packed Qualifier
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Structure ΓòÉΓòÉΓòÉ
-
- A structure declaration has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇstructΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇmemberΓöÇΓöÇ;ΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓöÇ><
- ΓööΓöÇidentifierΓöÇΓöÿ
-
- A structure member definition has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇtype_specifierΓöÇΓöÇΓöÇΓö¼ΓöÇdeclaratorΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ><
- ΓööΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ:ΓöÇΓöÇconstant_expressionΓöÇΓöÿ
- ΓööΓöÇ.declaratorΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.1. Initializing Structures ΓòÉΓòÉΓòÉ
-
- The initializer contains an = (equal sign) followed by a brace-enclosed
- comma-separated list of values. You do not have to initialize all members of a
- structure.
-
- The following definition shows a completely initialized structure:
-
- struct address {
- int street_no;
- char *street_name;
- char *city;
- char *prov;
- char *postal_code;
- };
- static struct address perm_address =
- { 3, "Savona Dr.", "Dundas", "Ontario", "L4B 2A1"};
-
- The values of perm_address are:
-
- Member Value
- perm_address.street_no 3
- perm_address.street_name address of string "Savona Dr."
- perm_address.city address of string "Dundas"
- perm_address.prov address of string "Ontario"
- perm_address.postal_code address of string "L4B 2A1"
-
- The following definition shows a partially initialized structure:
-
- struct address {
- int street_no;
- char *street_name;
- char *city;
- char *prov;
- char *postal_code;
- };
- struct address temp_address =
- { 44, "Knyvet Ave.", "Hamilton", "Ontario" };
-
- The values of temp_address are:
-
- Member Value
- temp_address.street_no 44
- temp_address.street_name address of string "Knyvet Ave."
- temp_address.city address of string "Hamilton"
- temp_address.prov address of string "Ontario"
- temp_address.postal_code value depends on the storage class.
-
- Note: The initial value of uninitialized structure members like
- temp_address.postal_code depends on the storage class associated with the
- member. See Storage Class Specifiers for details on the initialization of
- different storage classes.
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.2. Declaring Structure Types and Variables ΓòÉΓòÉΓòÉ
-
- To define a structure type and a structure variable in one statement, put a
- declarator and an optional initializer after the type definition. To specify a
- storage class specifier for the variable, you must put the storage class
- specifier at the beginning of the statement.
-
- For example:
-
- static struct {
- int street_no;
- char *street_name;
- char *city;
- char *prov;
- char *postal_code;
- } perm_address, temp_address;
-
- Because this example does not name the structure data type, perm_address and
- temp_address are the only structure variables that will have this data type.
- Putting an identifier after struct, lets you make additional variable
- definitions of this data type later in the program.
-
- The structure type (or tag) cannot have the volatile qualifier, but a member or
- a structure variable can be defined as having the volatile qualifier.
-
- For example:
-
- static struct class1 {
- char descript[20];
- volatile long code;
- short complete;
- } volatile file1, file2;
- struct class1 subfile;
-
- This example qualifies the structures file1 and file2, and the structure member
- subfile.code as volatile.
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.3. Declaring and Using Bit Fields in Structures ΓòÉΓòÉΓòÉ
-
- A structure or a C++ class can contain bit fields that allow you to access
- individual bits. You can use bit fields for data that requires just a few bits
- of storage. A bit field declaration contains a type specifier followed by an
- optional declarator, a colon, a constant expression, and a semicolon. The
- constant expression specifies how many bits the field reserves.
-
- Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot be
- referenced or initialized. A zero-width bit field causes the next field to be
- aligned on the next container boundary, where the container is the same size as
- the underlying type as the bit field. For a _Packed structure, a bit field of
- length 0 causes the next field to be aligned on the next byte boundary. The
- padding to the next container boundary only takes place if the zero-width bit
- field has the same underlying type as the preceding bit-field member. If the
- types are different, the zero-width bit field has no effect.
-
- The maximum bit-field length is implementation dependent. The maximum bit field
- length for the VisualAge for C++ compiler is 32 bits (4 bytes, or 1 word).
-
- For portability, do not use bit fields greater than 32 bits in size.
-
- The following restrictions apply to bit fields. You cannot:
-
- Define an array of bit fields
- Take the address of a bit field
- Have a pointer to a bit field
- Have a reference to a bit field (C++ only)
-
- In C, you can declare a bit field as type int, signed int, or unsigned int.
- Bit fields of the type int are equivalent to those of type unsigned int.
-
- The default integer type for a bit field is unsigned. Use the bitfields=signed
- option to change this default.
-
- In extended mode C, bit fields can be any integral type. For example,
-
- struct S {
- short x : 4;
- long y : 10;
- char z : 7;
- } s;
-
- Non-integral bit fields in extended mode C are converted to type unsigned int
- and a warning is issued. In other modes, the use of non-integral bit fields
- results in an error.
-
- A bit field cannot have the const or volatile qualifier.
-
- The following structure has three bit-field members kingdom, phylum, and
- genus, occupying 12, 6, and 2 bits respectively:
-
- struct taxonomy {
- int kingdom : 12;
- int phylum : 6;
- int genus : 2;
- };
-
- C++ Note: Unlike ANSI/ISO C, C++ bit fields can be any integral type or
- enumeration type. When you assign a value that is out of range to a bit field,
- the low-order bit pattern is preserved and the appropriate bits are assigned.
-
- If a series of bit fields does not add up to the size of an int, padding can
- take place. The amount of padding is determined by the alignment
- characteristics of the members of the structure. Bit fields cannot cross word
- boundaries but are forced to start at the next word boundary.
-
- The following example declares the identifier kitchen to be of type struct
- on_off:
-
- struct on_off {
- unsigned light : 1;
- unsigned toaster : 1;
- int count; /* 4 bytes */
- unsigned ac : 4;
- unsigned : 4;
- unsigned clock : 1;
- unsigned : 0;
- unsigned flag : 1;
- } kitchen ;
-
- The structure kitchen contains eight members totalling 16 bytes. The following
- table describes the storage that each member occupies:
-
- Member Name Storage Occupied
- light 1 bit
- toaster 1 bit
- (padding - 30 bits) To next int boundary
- count The size of an int
- ac 4 bits
- (unnamed field) 4 bits
- clock 1 bit
- (padding - 23 bits) To next int boundary (unnamed field)
- flag 1 bit
- (padding - 31 bits) To next int boundary
-
- All references to structure fields must be fully qualified. For instance, you
- cannot reference the second field by toaster. You must reference this field by
- kitchen.toaster.
-
- The following expression sets the light field to 1:
-
- kitchen.light = 1;
-
- When you assign to a bit field a value that is out of its range, the bit
- pattern is preserved and the appropriate bits are assigned. The following
- expression sets the toaster field of the kitchen structure to 0 because only
- the least significant bit is assigned to the toaster field:
-
- kitchen.toaster = 2;
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.4. Declaring a Packed Structure ΓòÉΓòÉΓòÉ
-
- Data elements of a structure are stored in memory on an address boundary
- specific for that data type. For example, a double value is stored in memory on
- a doubleword (8-byte) boundary. Gaps may be left in memory between elements of
- a structure to align elements on their natural boundaries. You can reduce the
- padding of bytes within a structure by using the _Packed qualifier on the
- structure declaration.
-
- C++ Note: C++ does not support the _Packed qualifier. To change the alignment
- of structures, use the #pragma pack directive or the /Sp compiler option. Both
- of these methods are also supported by C.
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.5. Anonymous Structures in C ΓòÉΓòÉΓòÉ
-
- Structures can be declared without declarators if they are members of another
- structure or union. Structures without declarators are called anonymous
- structures. They are only permitted in extended mode.
-
- Members of an anonymous structure can be accessed as if they were declared
- directly in the containing structure or union. For example, given the following
- structure:
-
- struct s {
- int a;
- struct {
- int b;
- float c;
- }; /* no declarator */
- } kim;
-
- you can make the following statements:
-
- kim.a = 5;
- kim.b = 36;
-
- You can also declare an anonymous structure:
-
- 1. By creating a typedef and using the typedef name without a declarator:
-
- typedef struct {
- int a;
- int b;
- } Struct_T;
-
- struct s1 {
- Struct_T;
- int c;
- } dave;
-
- 2. By using an existing structure tag without a declarator:
-
- struct s1 {
- int a;
- int b;
- };
-
- struct s2 {
- struct s1;
- int c;
- } dave;
-
- In both of the examples, the members can be accessed as dave.a, dave.b, and
- dave.c.
-
- An anonymous structure must be a member of, or nested within another anonymous
- structure that is a member of, a named structure or union. If a structure is
- declared at file scope without a declarator, its members are not available to
- the surrounding scope. For example, the following structure only declares the
- tag tom:
-
- struct tom {
- int b;
- float c;
- };
-
- The variables b and c from this structure cannot be used at file scope, and
- the following statements generate errors:
-
- b = 5;
- c = 2.5;
-
- C++ Note: Anonymous structures are treated differently in C++. See Anonymous
- Structures in C++ for more information.
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.6. Anonymous Structures in C++ ΓòÉΓòÉΓòÉ
-
- Anonymous structures are treated differently in the C++ language. Given these
- declarations:
-
- struct don {
- int a;
- int b;
- };
-
- struct pete {
- struct don;
- };
-
- In C, struct don; declares an anonymous structure as a member of pete. In C++,
- it is treated as a forward or incomplete declaration of a nested structure, not
- as an anonymous structure.
-
- A C++ anonymous structure is a structure without a class name. It cannot be
- followed by a declarator. An anonymous structure is not a type; it defines an
- unnamed object and it cannot have member functions.
-
- The member names of a C++ anonymous structure must be distinct from other names
- within the scope in which the structure is declared. You can use member names
- directly in the structure scope without any additional member access syntax.
-
- An anonymous structure cannot have protected or private members. A global
- anonymous structure must be declared with the keyword static.
-
-
- ΓòÉΓòÉΓòÉ 4.5.8.7. Example Program Using Structures ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program finds the sum of the integer numbers in a linked list:
-
- *
- ************************************************************************/
-
- /**
- ** Example program illustrating structures using linked lists
- **/
-
- #include <stdio.h>
-
- struct record {
- int number;
- struct record *next_num;
- };
-
- int main(void)
- {
- struct record name1, name2, name3;
- struct record *recd_pointer = &name1;
- int sum = 0;
-
- name1.number = 144;
- name2.number = 203;
- name3.number = 488;
-
- name1.next_num = &name2;
- name2.next_num = &name3;
- name3.next_num = NULL;
-
- while (recd_pointer != NULL)
- {
- sum += recd_pointer->number;
- recd_pointer = recd_pointer->next_num;
- }
- printf("Sum = %d\n", sum);
-
- return(0);
- }
-
- /************************************************************************
- *
-
- The structure type record contains two members: the integer number and
- next_num, which is a pointer to a structure variable of type record.
-
- The record type variables name1, name2, and name3 are assigned the following
- values:
-
- Member Name Value
- name1.number 144
- name1.next_num The address of name2
-
- name2.number 203
- name2.next_num The address of name3
-
- name3.number 488
- name3.next_num NULL (Indicating the end of the linked list.)
-
- The variable recd_pointer is a pointer to a structure of type record. It is
- initialized to the address of name1 (the beginning of the linked list).
-
- The while loop causes the linked list to be scanned until recd_pointer equals
- NULL. The statement:
-
- recd_pointer = recd_pointer->next_num;
-
- advances the pointer to the next object in the list.
-
- *
- ***********************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 4.5.9. Unions ΓòÉΓòÉΓòÉ
-
- A union is an object that can hold any one of a set of named members. The
- members of the named set can be of any data type. Members are overlaid in
- storage.
-
- The storage allocated for a union is the storage required for the largest
- member of the union (plus any padding that is required so that the union will
- end at a natural boundary of its strictest member).
-
- C++ Notes:
-
- In C++, a union can have member functions, including constructors and
- destructors, but not virtual member functions. A union cannot be used as a base
- class and cannot be derived from a base class.
-
- A C++ union member cannot be a class object that has a constructor, destructor,
- or overloaded copy assignment operator. In C++, a member of a union cannot be
- declared with the keyword static.
-
- A union type declaration contains the union keyword followed by an identifier
- (optional) and a brace-enclosed list of members.
-
- Syntax of a Union
-
- The identifier is a tag given to the union specified by the member list. If you
- specify a tag, any subsequent declaration of the union (in the same scope) can
- be made by declaring the tag and omitting the member list. If you do not
- specify a tag, you must put all variable definitions that refer to that union
- within the statement that defines the data type.
-
- The list of members provides the data type with a description of the objects
- that can be stored in the union.
-
- You can reference one of the possible members of a union the same way as
- referencing a member of a structure.
-
- For example:
-
- union {
- char birthday[9];
- int age;
- float weight;
- } people;
-
- people.birthday[0] = '\n';
-
- assigns '\n' to the first element in the character array birthday, a member of
- the union people.
-
- A union can represent only one of its members at a time. In the example, the
- union people contains either age, birthday, or weight but never more than one
- of these. The printf statement in the following example does not give the
- correct result because people.age replaces the value assigned to
- people.birthday in the first line:
-
- 1 people.birthday = "03/06/56";
- 2 people.age = 38;
- 3 printf("%s\n", people.birthday);
-
- Examples of Unions
-
- Additional information is provided on:
-
- Defining a Union Variable
- Defining a Packed Union
- Anonymous Unions in C
- Anonymous Unions in C++
-
- Related Information
-
- Dot Operator .
- Arrow Operator ->
- _Packed Qualifier
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Union ΓòÉΓòÉΓòÉ
-
- A union declaration has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇunionΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇmemberΓöÇΓöÇ;ΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓöÇ><
- ΓööΓöÇqualifierΓöÇΓöÿ ΓööΓöÇidentifierΓöÇΓöÿ
-
- A union member definition has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇtype_specifierΓöÇΓöÇΓöÇΓö¼ΓöÇdeclaratorΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ><
- ΓööΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ;ΓöÇΓöÇconstant_expressionΓöÇΓöÿ
- ΓööΓöÇdeclaratorΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.5.9.1. Defining a Union Variable ΓòÉΓòÉΓòÉ
-
- A union variable definition contains an optional storage class keyword, the
- union keyword, a union tag, and a declarator. The union tag indicates the data
- type of the union variable.
-
- The type specifier contains the keyword union followed by the name of the union
- type. You must declare the union data type before you can define a union having
- that type.
-
- You can define a union data type and a union of that type in the same statement
- by placing the variable declarator after the data type definition.
-
- The declarator is an identifier, possibly with the volatile or const qualifier.
-
- You can only initialize the first member of a union.
-
- The following example shows how you would initialize the first union member
- birthday of the union variable people:
-
- union {
- char birthday[9];
- int age;
- float weight;
- } people = {"23/07/57"};
-
- To define union type and a union variable in one statement, put a declarator
- after the type definition. The storage class specifier for the variable must go
- at the beginning of the statement.
-
-
- ΓòÉΓòÉΓòÉ 4.5.9.2. Defining Packed Unions ΓòÉΓòÉΓòÉ
-
- To qualify a C union as packed, use _Packed. The _Packed qualifier is only
- supported in C.
-
- Under the _Packed qualifier, the memory layout of the union members is not
- affected; Each member starts at offset zero. The _Packed qualifier does affect
- the total alignment restriction of the whole union.
-
- C++ Note: C++ does not support the _Packed qualifier. To change the alignment
- of C++ unions, use the #pragma pack directive or the /Sp compiler option. Both
- of these methods are also supported by C.
-
- In the following example, each of the elements in the nonpacked n_array is of
- type union uu.
-
- union uu {
- short a;
- struct {
- char x;
- char y;
- char z;
- } b;
- };
-
- union uu n_array[2];
- _Packed union uu p_array[2];
-
- Because it is not packed, each element in the nonpacked n_array has an
- alignment restriction of 2 bytes (the largest alignment requirement among the
- union members is that of short a), and there is 1 byte of padding at the end of
- each element to enforce this requirement.
-
- In the packed array p_array, each element is of type _Packed union uu. Because
- every element aligned on the byte boundary, each element has a length of only 3
- bytes, instead of the 4 bytes in the previous example.
-
-
- ΓòÉΓòÉΓòÉ 4.5.9.3. Anonymous Unions in C ΓòÉΓòÉΓòÉ
-
- Unions can be declared without declarators if they are members of another
- structure or union. Unions without declarators are called anonymous unions.
-
- Members of an anonymous union can be accessed as if they were declared directly
- in the containing structure or union. For example, given the following
- structure:
-
- struct s {
- int a;
- union {
- int b;
- float c;
- }; /* no declarator */
- } kurt;
-
- you can make the following statements:
-
- kurt.a = 5;
- kurt.b = 36;
-
- You can also declare an anonymous union:
-
- 1. By creating a typedef and using the typedef name without a declarator:
-
- typedef union {
- int a;
- int b;
- } UNION_T;
-
- struct s1 {
- UNION_T;
- int c;
- } dave;
-
- 2. By using an existing union tag without a declarator:
-
- union u1 {
- int a;
- int b;
- };
-
- struct s1 {
- union u1;
- int c;
- } dave;
-
- In both of the examples, the members can be accessed as dave.a, dave.b, and
- dave.c.
-
- An anonymous union must be a member of, or nested within another anonymous
- union that is a member of, a named structure or union. If a union is declared
- at file scope without a declarator, its members are not available to the
- surrounding scope. For example, the following union only declares the union
- tag tom:
-
- union tom {
- int b;
- float c;
- };
-
- The variables b and c from this union cannot be used at file scope, and the
- following statements will generate errors:
-
- b = 5;
- c = 2.5;
-
- C++ Note: Anonymous unions are treated differently in C++. See Anonymous
- Unions in C++ for more information.
-
-
- ΓòÉΓòÉΓòÉ 4.5.9.4. Anonymous Unions in C++ ΓòÉΓòÉΓòÉ
-
- It cannot be followed by a declarator. An anonymous union is not a type; it
- defines an unnamed object and it cannot have member functions.
-
- The member names of an anonymous union must be distinct from other names within
- the scope in which the union is declared. You can use member names directly in
- the union scope without any additional member access syntax.
-
- For example, in the following code fragment, you can access the data members i
- and cptr directly because they are in the scope containing the anonymous union.
- Because i and cptr are union members and have the same address, you should only
- use one of them at a time. The assignment to the member cptr will change the
- value of the member i.
-
- void f()
- {
- union { int i; char* cptr ; };
- // .
- // .
- // .
- i = 5;
- cptr = "string_in_union"; // overrides i
- }
-
- An anonymous union cannot have protected or private members. A global anonymous
- union must be declared with the keyword static.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Unions ΓòÉΓòÉΓòÉ
-
- The following example defines a union data type (not named) and a union
- variable (named length). The member of length can be a long int, a float, or a
- double.
-
- union {
- float meters;
- double centimeters;
- long inches;
- } length;
-
- The following example defines the union type data as containing one member. The
- member can be named charctr, whole, or real. The second statement defines two
- data type variables: input and output.
-
- union data {
- char charctr;
- int whole;
- float real;
- };
- union data input, output;
-
- The following statement assigns a character to input:
-
- input.charctr = 'h';
-
- The following statement assigns a floating-point number to member output:
-
- output.real = 9.2;
-
- The following example defines an array of structures named records. Each
- element of records contains three members: the integer id_num, the integer
- type_of_input, and the union variable input. input has the union data type
- defined in the previous example.
-
- struct {
- int id_num;
- int type_of_input;
- union data input;
- } records[10];
-
- The following statement assigns a character to the structure member input of
- the first element of records:
-
- records[0].input.charctr = 'g';
-
-
- ΓòÉΓòÉΓòÉ 4.6. Declarators ΓòÉΓòÉΓòÉ
-
- A declarator designates a data object or function. Declarators appear in all
- data definitions and declarations and in some type definitions.
-
- In a declarator, you can specify the type of an object to be an array, a
- pointer, or a reference. You can specify that the return type of a function is
- a pointer or a reference. You can also perform initialization in a declarator.
-
- Syntax of a Declarator VisualAge for C++ also recognizes the following
- qualifiers:
-
- _Packed, described on page _Packed Qualifier
- __unaligned, described on page __unaligned Type Qualifier
-
- You can also use the following specifiers at the beginning of a declarator:
-
- _Export, described on page _Export Keyword
- _Import, described on page _Import Keyword
- __thread, described on page __thread Keyword
- __declspec, described on page __declspec Keyword
-
- In C, you cannot declare or define a volatile or const function. C++ class
- member functions can be qualified with const or volatile. A subscript
- declarator has the form:
-
- >>ΓöÇΓöÇ[ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ]ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇconstant_expressionΓöÇΓöÿ Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇ[ΓöÇΓöÇconstant_expressionΓöÇΓöÇ]ΓöÇΓö┤ΓöÇΓöÿ
-
- A simple declarator consists of an identifier, which names a data object. For
- example, the following block scope data declaration uses initial as the
- declarator:
-
- auto char initial;
-
- The data object initial has the storage class auto and the data type char.
-
- You can define or declare a structure, union, or array. by using a declarator
- that contains an identifier, which names the data object, and some combination
- of symbols and identifiers, which describes the type of data that the object
- represents.
-
- The following declaration uses compute[5] as the declarator:
-
- extern long int compute[5];
-
- Examples of Declarators
-
- Related Information
-
- volatile and const Qualifiers
- _Packed Qualifier
- _Export Keyword
- __unaligned Type Qualifier
- Declarations
- Arrays
- Enumerations
- Pointers
- Structures
- Unions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Declarator Syntax ΓòÉΓòÉΓòÉ
-
- A declarator has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓö┤ΓöÇΓöÇ>
- ΓööΓöÇ*ΓöÇΓöÿ Γö£ΓöÇvolatileΓöÇΓöñ
- ΓööΓöÇconstΓöÇΓöÇΓöÇΓöÇΓöÿ
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇidentifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓö┤ΓöÇΓöÇ><
- ΓööΓöÇ(ΓöÇΓöÇdeclaratorΓöÇΓöÇ)ΓöÇΓöÿ Γö£ΓöÇsubscript_declaratorΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇ(ΓöÇΓöÇparameter_type_listΓöÇΓöÇ)ΓöÇΓöñ
- ΓööΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
- ΓööΓöÇidentifierΓöÇΓöÿ
-
- A qualifier is one of: const, volatile or _Packed. The VisualAge for C++
- compiler also implements the __unaligned qualifier.
-
- C++ Note: C++ does not support the _Packed keyword.
-
- A declarator can contain a subdeclarator. A subdeclarator has the form:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇidentifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ>
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé ΓööΓöÇ(ΓöÇΓöÇsubdeclaratorΓöÇΓöÇ)ΓöÇΓöÿ
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ*ΓöÇΓö┤ΓöÇΓöÿ
- Γö£ΓöÇvolatileΓöÇΓöñ
- ΓööΓöÇconstΓöÇΓöÇΓöÇΓöÇΓöÿ
- >ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇsubscript_declaratorΓöÇΓöÿ
-
- A subscript declarator describes the number of dimensions in an array and the
- number of elements in each dimension. A subscript declarator has the form:
-
- >>ΓöÇΓöÇ[ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ]ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇconstant_expressionΓöÇΓöÿ Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇ[ΓöÇΓöÇconstant_expressionΓöÇΓöÇ]ΓöÇΓö┤ΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 4.6.1. volatile and const Qualifiers ΓòÉΓòÉΓòÉ
-
- The volatile qualifier maintains consistency of memory access to data objects.
- It tells the compiler that the variable should always contain its current value
- even when optimized, so that the variable can be queried when an exception
- occurs. Volatile objects are read from memory each time their value is needed,
- and written back to memory each time they are changed.
-
- The volatile qualifier is useful for data objects having values that may be
- changed in ways unknown to your program (such as the system clock). Objects
- referenced by multiple threads or by signal handlers should also be qualified
- as volatile. Portions of an expression that reference volatile objects are not
- to be changed or removed.
-
- The const qualifier explicitly declares a data object as a data item that
- cannot be changed. Its value is set at initialization. You cannot use const
- data objects in expressions requiring a modifiable lvalue. For example, a const
- data object cannot appear on the left-hand side of an assignment statement.
-
- These type qualifiers are only meaningful in expressions that are lvalues.
-
- For a volatile or const pointer, you must put the keyword between the * and the
- identifier. For example:
-
- int * volatile x; /* x is a volatile pointer to an int */
- int * const y = &z; /* y is a const pointer to the int variable z */
-
- For a pointer to a volatile or const data object, the type specifier,
- qualifier, and storage class specifier can be in any order. For example:
-
- volatile int *x; /* x is a pointer to a volatile int */
- or
- int volatile *x; /* x is a pointer to a volatile int */
-
- const int *y; /* y is a pointer to a const int */
- or
- int const *y; /* y is a pointer to a const int */
-
- In the following example, the pointer to y is a constant. You can change the
- value that y points to, but you cannot change the value of y:
-
- int * const y
-
- In the following example, the value that y points to is a constant integer and
- cannot be changed. However, you can change the value of y:
-
- const int * y
-
- For other types of volatile and const variables, the position of the keyword
- within the definition (or declaration) is less important. For example:
-
- volatile struct omega {
- int limit;
- char code;
- } group;
-
- provides the same storage as:
-
- struct omega {
- int limit;
- char code;
- } volatile group;
-
- In both examples, only the structure variable group receives the volatile
- qualifier. Similarly, if you specified the const keyword instead of volatile,
- only the structure variable group receives the const qualifier. The const and
- volatile qualifiers when applied to a structure, union, or class also apply to
- the members of the structure, union, or class.
-
- Although enumeration, structure, and union variables can receive the volatile
- or const qualifier, enumeration, structure, and union tags do not carry the
- volatile or const qualifier. For example, the blue structure does not carry the
- volatile qualifier:
-
- volatile struct whale {
- int weight;
- char name[8];
- } beluga;
- struct whale blue;
-
- The keywords volatile and const cannot separate the keywords enum, struct, and
- union from their tags.
-
- You can declare or define a volatile or const function only if it is a C++
- member function. You can define or declare any function to return a pointer to
- a volatile or const function.
-
- You can put more than one qualifier on a declaration but you cannot specify the
- same qualifier more than once on a declaration.
-
- Related Information
-
- Declarators
- _Packed Qualifier
- __unaligned Type Qualifier
- Type Specifiers
- Structures
- Unions
- Enumerations
- Pointers
- lvalues
-
-
- ΓòÉΓòÉΓòÉ 4.6.2. _Packed Qualifier ΓòÉΓòÉΓòÉ
-
- The _Packed qualifier removes padding between members of structures and affects
- the alignment of unions whenever possible. However, the storage saved using
- packed structures and unions may come at the expense of runtime performance.
- Most machines access data more efficiently if it is aligned on appropriate
- boundaries. With packed structures and unions, members are generally not
- aligned on natural boundaries, and the result is that member-accessing
- operations (using the . and -> operators) are slower.
-
- _Packed can only be used with structures or unions. If you use _Packed with
- other types, an error message is generated and the qualifier has no effect on
- the declarator it qualifies. Packed and nonpacked structures and unions have
- different storage layouts. Comparisons between packed and nonpacked structures
- or unions of the same type are prohibited.
-
- If you specify the _Packed qualifier on a structure or union that contains a
- structure or union as a member, the qualifier is not passed on to the contained
- structure or union.
-
- The VisualAge for C++ compiler also lets you pack structures using the #pragma
- pack directive or the /Sp option.
-
- C++ Note: C++ does not support the _Packed keyword. Use the #pragma pack
- directive or the /Sp compiler option to control the alignment of structures and
- unions.
-
- Related Information
-
- #pragma pack
- /Sp option
- Declarators
- volatile and const Qualifiers
- __unaligned Type Qualifier
- _Export Keyword
- _Import Keyword
- Type Specifiers
- Structures
- Unions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Declarators ΓòÉΓòÉΓòÉ
-
- The following table describes some declarators:
-
- Example Description
-
- int owner owner is an int data object.
-
- int *node node is a pointer to an int data object.
-
- int names[126] names is an array of 126 int elements.
-
- int *action( ) action is a function returning a pointer to an int.
-
- volatile int min min is an int that has the volatile
-
- int * volatile volume volume is a volatile pointer to an int.
-
- volatile int * next next is a pointer to a volatile int
-
- volatile int * sequence[5] sequence is an array of five pointers to volatile
- int objects.
-
- extern const volatile int op_system_clock op_system_clock is an extern int
- that has the volatile attribute.
-
-
- ΓòÉΓòÉΓòÉ 4.6.3. __unaligned Type Qualifier ΓòÉΓòÉΓòÉ
-
- In most cases, data is aligned along the natural boundaries of the machine
- word. On some architectures, when data is not natuarally aligned, the operating
- system generates an exception. In order to minimize unaligned data access
- exceptions for objects that you know will not be naturally aligned, use the
- __unaligned type qualifier.
-
- The __unaligned qualifier can only be used with pointers or typedefs.
-
- The following are valid declarations with the __unaligned qualifier:
-
- // These are just the declaration examples from the feature.
- // A more extensive example would be nice.
-
- __unaligned int *pegasus;
- int * __unaligned *jupiter;
- typedef unaligned float flt_type;
- __unaligned struct *oscar;
- __unaligned _Packed struct *oscar; //redundant, see note
-
- Note: You do not need to use the __unaligned qualifier for packed structures,
- unions, and classes, because the _Packed qualifier or #pragma pack specifies
- the alignment of aggregates and their members.
-
- In declarations that are not typedefs, the __unaligned qualifier is bound to
- the type that is pointed to, not the pointer. The following declarations with
- the __unaligned qualifier are not valid:
-
- __unaligned int othneilia;
- int * __unaligned camptosaur;
- __unaligned struct troodon { /* ... */ } baryonyx;
-
- Related Information
-
- Pointers
- Declarators
- volatile and const Qualifiers
- _Packed Qualifier
- Structures
- Unions
-
-
- ΓòÉΓòÉΓòÉ 4.6.4. _Export Keyword ΓòÉΓòÉΓòÉ
-
- Use the _Export keyword with a function name or external variable to declare
- that the function or variable is to be exported; that is, made available to
- other modules. For example:
-
- int _Export anthony(float);
-
- causes the function anthony to be exported if it is defined within the
- compilation unit. The function must be defined in the same compilation unit in
- which the _Export keyword is used.
-
- _Export is allowed only at file scope. It is not allowed in a declaration that
- already contains _Import, and it cannot be used in a typedef. The _Export
- keyword cannot be applied to the return type of a function. For example, the
- declaration
-
- int _Export * a(); // error
-
- causes an error.
-
- If the _Export keyword is repeated in a declaration, a warning is issued when
- the /Wgen option is specified. If a name is redeclared with conflicting _Export
- or _Import qualifiers, an error message is issued.
-
- Since _Export is part of the declarator, it affects only the closest
- identifier. In the declaration
-
- int _Export a, b;
-
- _Export only modifies a.
-
- You can use _Export at any language level.
-
- If you also use linkage keywords, you can place _Export either before or after
- a linkage keyword. For example, both of the following declarations are valid:
-
- int _Export _Optlink brian(int);
- int _Optlink _Export brian(int);
-
- You can also mark exports with the #pragma export directive or the
- __declspec(dllexport) construct.
-
- Thread-local data cannot be imported or exported.
-
- If you use _Export to export your function, you may still need to provide an
- EXPORTS entry for that function in your module definition (.DEF) file. If your
- function has any of the following default characteristics
-
- Has shared data
- Has no I/O privileges
- Is not resident
-
- it does not require an EXPORTS entry. If your function has characteristics
- other than the defaults, the only way you can specify them is with an EXPORTS
- entry in your .DEF file.
-
- Note: To create an import library for the DLL, and you are not passing
- objects to ILIB, you must provide a .DEF file with an EXPORTS entry for every
- function. You can create the .DEF file from the DLL itself. The description of
- ILIB in the IBM VisualAge for C++ for Windows User's Guide describes how to do
- this.
-
- No .DEF file is needed if you use _Export on all exports and the object files
- are passed to the ILIB program.
-
- For more information on DLLs, .DEF files, and exporting functions, see the IBM
- VisualAge for C++ for Windows Programming Guide.
-
- Related Information
-
- #pragma export
- #pragma import
- Declarators
- volatile and const Qualifiers
- _Packed Qualifier
- __unaligned Type Qualifier
- __thread Keyword
- __declspec Keyword
- Assembler Declarations (asm Keyword)
- _asm and __asm Keywords
-
-
- ΓòÉΓòÉΓòÉ 4.6.5. _Import Keyword ΓòÉΓòÉΓòÉ
-
- Use the _Import keyword with a function name or external variable to declare
- that the function or variable is to be imported from a DLL. For example:
-
- int _Import anthony(float);
-
- causes the function anthony to be imported. You must mark data imports by
- _Import or __declspec(dllimport). Code is generated more efficiently if you
- also mark function imports this way.
-
- Thread-local data cannot be imported or exported.
-
- _Import is allowed at file scope and at block scope with the extern storage
- class specifier. It is not allowed in a declaration that already contains
- _Export, and it cannot be used in a typedef. _Import is not allowed on a
- defined external. The following declaration gives an error:
-
- int _Import jill = 0;
-
- An external pointer cannot be initialized with the address of an imported C
- variable. This is allowed in C++. Both C and C++ allow a function pointer to be
- statically initialized to the address of an imported function.
-
- If the _Import keyword is repeated in a declaration, a warning is issued when
- the /Wgen option is specified. If a name is redeclared with conflicting _Import
- or _Export qualifiers, an error message is issued. If _Import is specified and
- the variable is defined later, _Export is assumed, and a warning is issued if
- the /Wdcl option is specified. For example:
-
- extern int _Import joe;
- int joe; // Warning issued with /Wdcl and joe is exported
-
- Since _Import is part of the declarator, it affects only the closest
- identifier. In the declaration
-
- int _Import a, b;
-
- _Import only modifies a.
-
- You can use _Import at any language level.
-
- If you also use linkage keywords, you can place _Import either before or after
- a linkage keyword. For example, both of the following declarations are valid:
-
- int _Import _Optlink brian(int);
- int _Optlink _Import brian(int);
-
- For more information on DLLs and importing functions see the IBM VisualAge for
- C++ for Windows Programming Guide.
-
- Related Information
-
- #pragma export
- #pragma import
- Declarators
- volatile and const Qualifiers
- _Packed Qualifier
- _Export Keyword
- __thread Keyword
- __declspec Keyword
-
-
- ΓòÉΓòÉΓòÉ 4.6.6. __thread Keyword ΓòÉΓòÉΓòÉ
-
- Use the __thread keyword with an external variable to allow each thread in
- multi-threaded process to allocate storage for its corresponding data. This
- storage is referred to as thread-local storage (TLS).
-
- Defining and initializing thread-local storage data is similar to defining and
- initializing ordinary static variables.
-
- Thread-local storage data objects are declared with the __thread keyword, which
- can apply to three kinds of data:
-
- Global data objects (static and extern)
- Local static data objects
- Static data members of a class
-
- Thread-local data cannot be imported or exported.
-
- Refer to the IBM VisualAge for C++ for Windows Programming Guide for a full
- description of using thread-local storage.
-
- The #pragma data_seg directive does not affect the thread-local storage data
- segment.
-
- Thread-local storage objects can also be declared with the __declspec keyword.
- For example,
-
- __declspec(thread) int tls_i;
-
- is equivalent to:
-
- __thread int tls_i;
-
- C++ Note: In C++, for a given thread:
-
- Each time a thread is created, the constructor of the thread object is
- called.
- Each time a thread is terminated, the destructor of the thread object is
- called.
-
- Related Information
-
- extern Storage Class Specifier
- static Storage Class Specifier
- Declarators
- volatile and const Qualifiers
- _Packed Qualifier
- _Export Keyword
- _Import Keyword
- __declspec Keyword
-
-
- ΓòÉΓòÉΓòÉ 4.6.7. __declspec Keyword ΓòÉΓòÉΓòÉ
-
- Use the __declspec keyword to declare imported or exported functions and
- variables, or to declare thread-local storage (TLS) objects.
-
- The __declspec keyword is allowed anywhere in the declaration specifier. It is
- used with the following sub-specifiers:
-
- dllexport Declares that the function or variable is to be exported; that is,
- made available to other modules. __declspec(dllexport) is
- equivalent to the _Export specifier, described in _Export Keyword.
-
- dllimport Declares that the function or variable is to be imported from a
- DLL. __declspec(dllimport) is equivalent to the _Import specifier,
- described in _Import Keyword.
-
- __declspec(dllimport) implies extern. For example, the declaration
- int __declspec(dllimport) b; is equivalent to extern int
- __declspec(dllimport) b; You must mark data imports by _Import or
- __declspec(dllimport). Code is generated more efficiently if you
- also mark function imports this way.
-
- thread Declares thread-local storage variables, which allow each thread
- in multi-threaded process to allocate storage for its
- corresponding data. __declspec(thread) is equivalent to the
- __thread specifier, described in __thread Keyword.
-
- Only __declspec (and _declspec) are keywords; the sub-specifiers are not.
-
- In the following declaration, function a() is exported:
-
- int __declspec(dllexport) * a();
-
- Unlike _Export and _Import, which are part of the declarator,
- __declspec(dllexport) applies to the entire declaration list. In the following
- declaration, __declspec(dllexport) applies to both a and b:
-
- __declspec(dllexport) int a, b;
-
- The __declspec construct is not allowed in a typedef.
-
- The address of a name imported with __declspec(dllimport) is not considered a
- constant; any expression involving such an address is not a constant
- expression.
-
- An external pointer cannot be initialized with the address of an imported C
- variable. This is allowed in C++. Both C and C++ allow a function pointer to
- be statically initialized to the address of an imported function.
-
- Note: The Microsoft Visual C++ sub-specifier naked is not supported by
- VisualAge for C++. A warning is issued if it is used.
-
- Related Information
-
- Declarators
- volatile and const Qualifiers
- _Packed Qualifier
- _Export Keyword
- _Import Keyword
- __thread Keyword
- #pragma export
-
-
- ΓòÉΓòÉΓòÉ 4.7. Initializers ΓòÉΓòÉΓòÉ
-
- An initializer is an optional part of a data declaration that specifies an
- initial value of a data object.
-
- Syntax of an Initializer
-
- The initializer consists of the = symbol followed by an initial expression or a
- braced list of initial expressions separated by commas. The number of
- initializers must not be more than the number of elements to be initialized. An
- initializer list with fewer initializers than elements, can end with a comma,
- indicating that the rest of the uninitialized elements are initialized to zero.
- The initial expression evaluates to the first value of the data object.
-
- To assign a value to a scalar object, use the simple initializer: = expression.
- For example, the following data definition uses the initializer = 3 to set the
- initial value of group to 3:
-
- int group = 3;
-
- For unions, structures, and aggregate classes (classes with no constructors,
- base classes, virtual functions, or private or protected members), the set of
- initial expressions must be enclosed in { } (braces) unless the initializer is
- a string literal.
-
- If the initializer of a character string is a string literal, the { } are
- optional. Individual expressions must be separated by commas, and groups of
- expressions can be enclosed in braces and separated by commas.
-
- In an array, structure, or union initialized using a brace-enclosed initializer
- list, any members or subscripts that are not initialized are implicitly
- initialized to zero of the appropriate type.
-
- The initialization properties of each data type are described in the section
- for that data type.
-
- Note:
-
- 1. An initializer of the form (expression) can be used to initialize
- fundamental types in C++. For example, the following two initializations
- are identical:
-
- int group = 3;
- int group(3);
-
- 2. You can also use the (expression) form to initialize C++ classes. For
- more information on initializing classes, see Initialization by
- Constructor.
-
- 3. You can initialize variables at file scope with nonconstant expressions.
- This is not allowed in ANSI/ISO C.
-
- 4. If your code jumps over declarations that contain initializations, the
- compiler generates an error. For example, the following code is not valid
- in C++:
-
- goto skiplabel; // error - jumped over declaration
- int i = 3; // and initialization of i
-
- skiplabel: i = 4;
-
- 5. You can initialize classes in external, static, and automatic
- definitions. The initializer contains an = (equal sign) followed by a
- brace-enclosed, comma-separated list of values. You do not need to
- initialize all members of a class.
-
- In the following example, only the first eight elements of the array grid are
- explicitly initialized. The remaining four elements that are not explicitly
- initialized are initialized as if they were explicitly initialized to zero.
-
- static short grid[3] [4] = {0, 0, 0, 1, 0, 0, 1, 1};
-
- The initial values of grid are:
-
- Element Value
- grid[0][0] 0
- grid[0][1] 0
- grid[0][2] 0
- grid[0][3] 1
- grid[1][0] 0
- grid[1][1] 0
- grid[1][2] 1
- grid[1][3] 1
- grid[2][0] 0
- grid[2][1] 0
- grid[2][2] 0
- grid[2][3] 0
-
- Related Information
-
- Block Scope Data Declarations
- File Scope Data Declarations
- Arrays
- Characters
- Enumerations
- Floating-Point Variables
- Integer Variables
- Pointers
- Structures
- Unions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Initializer Syntax ΓòÉΓòÉΓòÉ
-
- An initializer has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓö¼ΓöÇ(ΓöÇΓöÇΓöÇexpressionΓöÇΓö┤ΓöÇ)ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ=ΓöÇΓöÇΓö¼ΓöÇexpressionΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇ{ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇexpressionΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ}ΓöÇΓöÿ
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé Γöé
- Γöé Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇexpressionΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓö┤ΓöÇΓöÿ
-
- The form (expression) is allowed in C++ only.
-
-
- ΓòÉΓòÉΓòÉ 4.8. Function Specifiers ΓòÉΓòÉΓòÉ
-
- The function specifiers inline and virtual are used only in C++ function
- declarations, which are described on page Function Declarations.
-
- The function specifier inline is used to make a suggestion to the compiler to
- incorporate the code of a function into the code at the point of the call. For
- more information, see Inline Functions.
-
- The function specifier virtual can only be used in nonstatic member function
- declarations. For more information, see Virtual Functions.
-
-
- ΓòÉΓòÉΓòÉ 4.9. References ΓòÉΓòÉΓòÉ
-
- A C++ reference is an alias or an alternative name for an object. All
- operations applied to a reference act on the object the reference refers to.
- The address of a reference is the address of the aliased object.
-
- A reference type is defined by placing the & after the type specifier. You must
- initialize all references except function parameters when they are defined.
-
- Because arguments of a function are passed by value, a function call does not
- modify the actual values of the arguments. If a function needs to modify the
- actual value of an argument, the argument must be passed by reference (as
- opposed to being passed by value). Passing arguments by reference can be done
- using either references or pointers. In C++, this is accomplished
- transparently. Unlike C, C++ does not force you to use pointers if you want to
- pass arguments by reference. For example:
-
- int f(int&);
- void main()
- {
- extern int i;
- f(i);
- }
-
- You cannot tell from the function call f(i) that the argument is being passed
- by reference.
-
- References to NULL are not allowed.
-
- Additional information is provided on Initializing References.
-
- Related Information
-
- Passing Arguments by Reference
- Pointers
- Declarators
- Initializers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Initializing References ΓòÉΓòÉΓòÉ
-
- The object that you use to initialize a reference must be of the same type as
- the reference, or it must be of a type that is convertible to the reference
- type. If you initialize a reference to a constant using an object that requires
- conversion, a temporary object is created. In the following example, a
- temporary object of type float is created:
-
- int i;
- const float& f = i; // reference to a constant float
-
- Attempting to initialize a nonconstant reference with an object that requires a
- conversion is an error.
-
- Once a reference has been initialized, it cannot be modified to refer to
- another object. For example:
-
- int num1 = 10;
- int num2 = 20;
-
- int &RefOne = num1; // valid
- int &RefOne = num2; // error, two definitions of RefOne
- RefOne = num2; // assign num2 to num1
- int &RefTwo; // error, uninitialized reference
- int &RefTwo = num2; // valid
-
- Note that the initialization of a reference is not the same as an assignment to
- a reference. Initialization operates on the actual reference by initializing
- the reference with the object it is an alias for. Assignment operates through
- the reference on the object referred to.
-
- A reference can be declared without an initializer:
-
- When it is used in an argument declaration
- In the declaration of a return type for a function call
- In the declaration of class member within its class declaration
- When the extern specifier is explicitly used.
-
- You cannot have references to any of:
-
- Other references
- Bit fields
- Arrays of references
- Pointers to references
- Additional information is provided on Initializing References.
-
- Related Information
-
- Passing Arguments by Reference
- Pointers
- Declarators
- Initializers
- Temporary Objects
-
-
- ΓòÉΓòÉΓòÉ 4.10. Assembler Declarations (asm Keyword) ΓòÉΓòÉΓòÉ
-
- The asm keyword is used to pass information through the compiler to the
- assembler. An asm declaration has the form:
-
- >>ΓöÇΓöÇasmΓöÇΓöÇ(ΓöÇΓöÇstring_literalΓöÇΓöÇ)ΓöÇΓöÇ;ΓöÇΓöÇ><
-
- The string_literal can be any arbitrary text.
-
- Note: The asm keyword is recognized by VisualAge for C++, but no code is
- generated for the inlined assembler instructions.
-
- For example, the compiler accepts the string literal in the following asm
- declaration, but a warning is issued:
-
- asm (VULTURES ARE COWARDLY AND SUPERSTITIOUS);
-
- Valid assembler instructions are also permitted, but no code is generated:
-
- asm (mov ax, bx __asm mov bx, ax __asm mov ax, bx);
-
-
- ΓòÉΓòÉΓòÉ 5. Expressions and Operators ΓòÉΓòÉΓòÉ
-
- Expressions are sequences of operators, operands, and punctuators that specify
- a computation. The evaluation of expressions is based on the operators that the
- expressions contain and the context in which they are used.
-
- This section discusses:
-
- Primary Expressions
- Unary Expressions
- Binary Expressions
- Conditional Expressions
- Assignment Expressions
- Comma Expression ,
- lvalues
- Constant Expressions
-
- An expression can result in an lvalue, rvalue, or no value, and can produce
- side effects in each case.
-
- C++ Note: C++ operators can be defined to behave differently when applied to
- operands of class type. This is called operator overloading. This section
- describes the behavior of operators that are not overloaded. The C language
- does not permit overloading.
-
- Related Information
-
- Declarations
- Overloading Operators
-
-
- ΓòÉΓòÉΓòÉ 5.1. Operator Precedence and Associativity ΓòÉΓòÉΓòÉ
-
- Two operator characteristics determine how operands group with operators:
- precedence and associativity. Precedence is the priority for grouping different
- types of operators with their operands. Associativity is the left-to-right or
- right-to-left order for grouping operands to operators that have the same
- precedence.
-
- For example, in the following statements, the value of 5 is assigned to both a
- and b because of the right-to-left associativity of the = operator. The value
- of c is assigned to b first, and then the value of b is assigned to a.
-
- b = 9;
- c = 5;
- a = b = c;
-
- Because the order of subexpression evaluation is not specified, you can
- explicitly force the grouping of operands with operators by using parentheses.
-
- In the expression a + b * c / d, the * and / operations are performed before +
- because of precedence. b is multiplied by c before it is divided by d because
- of associativity.
-
- Table of Operator Precedence and Associativity lists the C and C++ language
- operators in order of precedence and shows the direction of associativity for
- each operator. In C++, the primary scope resolution operator (::) has the
- highest precedence, followed by the other primary operators. In C, because
- there is no scope resolution operator, the other primary operators have the
- highest precedence. The comma operator has the lowest precedence. Operators
- that appear in the same group have the same precedence.
-
- The order of evaluation for function call arguments or for the operands of
- binary operators is not specified. Avoid writing such ambiguous expressions as:
-
- z = (x * ++y) / func1(y);
- func2(++i, x[i]);
-
- In the example above, the order of evaluation of ++y and func1(y) is not
- defined. If y had the value of 1 before the first statement, it is not known
- whether or not the value of 1 or 2 is passed to func1(). In the second
- statement, if i had the value of 1, it is not known whether the first or second
- array element of x[ ] is passed as the second argument to func2(). Do not write
- code that depends on a particular order of evaluation of operators with the
- same precedence.
-
- The order of grouping operands with operators in an expression containing more
- than one instance of an operator with both associative and commutative
- properties is not specified. The operators that have the same associative and
- commutative properties are: *, +, &, |, and ^ (or ╨║). The grouping of operands
- can be forced by grouping the expression in parentheses.
-
- Examples of Expressions and Precedence
-
- Related Information
-
- Parenthesized Expressions ( )
- Expressions and Operators
- Table of Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Expressions and Precedence ΓòÉΓòÉΓòÉ
-
- The parentheses in the following expressions explicitly show how the compiler
- groups operands and operators. If parentheses did not appear in these
- expressions, the operands and operators are grouped in the same manner as
- indicated by the parentheses.
-
- total = (4 + (5 * 3));
- total = (((8 * 5) / 10) / 3);
- total = (10 + (5/3));
-
- Because the order of grouping operands with operators that are both associative
- and commutative is not specified, the compiler can group the operands and
- operators in the expression:
-
- total = price + prov_tax + city_tax;
-
- in the following ways (as indicated by parentheses):
-
- total = (price + (prov_tax + city_tax));
- total = ((price + prov_tax) + city_tax);
- total = ((price + city_tax) + prov_tax);
-
- If the values in this expression are integers, the grouping of operands and
- operators does not affect the result. Because intermediate values are rounded,
- different groupings of floating-point operators may give different results.
-
- In certain expressions, the grouping of operands and operators can affect the
- result. For example, in the following expression, each function call might be
- modifying the same global variables.
-
- a = b() + c() + d();
-
- This expression can give different results depending on the order in which the
- functions are called.
-
- If the expression contains operators that are both associative and commutative
- and the order of grouping operands with operators can affect the result of the
- expression, separate the expression into several expressions. For example, the
- following expressions could replace the previous expression if the called
- functions do not produce any side effects that affect the variable a.
-
- a = b();
- a += c();
- a += d();
-
- Integer overflows are ignored. Division by zero and floating-point exceptions
- are implementation dependent.
-
- See the IBM VisualAge for C++ for Windows User's Guide for information about
- VisualAge for C++ implementation dependencies.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Table of Operator Precedence and Associativity ΓòÉΓòÉΓòÉ
-
- Operator Name Operators
-
- Primary scope resolution ::
- Associativity: left to right
-
- Primary () [ ] . -> (type_name)
- Associativity: left to right
-
- Unary ++ -- - + ! ~ & * sizeof new delete
- (typename) (C cast)
- Associativity: right to left
-
- C++ Cast (typename)
- Associativity: left to right
-
- C++ Pointer to Member .* ->*
- Associativity: left to right
-
- Multiplicative * / %
- Associativity: left to right
-
- Additive + -
- Associativity: left to right
-
- Bitwise Shift << >>
- Associativity: left to right
-
- Relational < > <= >=
- Associativity: left to right
-
- Equality == !=
- Associativity: left to right
-
- Bitwise Logical AND &
- Associativity: left to right
-
- Bitwise Exclusive OR ^ or ╨║
- Associativity: left to right
-
- Bitwise Inclusive OR |
- Associativity: left to right
-
- Logical AND &&
- Associativity: left to right
-
- Logical OR ||
- Associativity: left to right
-
- Conditional ? :
- Associativity: right to left
-
- Assignment = += -= *= /= <<= >>= %= &= ^= |=
- Associativity: right to left
-
- Comma ,
- Associativity: left to right
-
-
- ΓòÉΓòÉΓòÉ 5.2. Operands ΓòÉΓòÉΓòÉ
-
- Most expressions can contain several different, but related, types of operands.
- The following type classes describe related types of operands:
-
- Integral Character objects and constants, objects having an enumeration
- type, and objects having the type short, int, long, unsigned
- short, unsigned int, unsigned long, long long, or unsigned long
- long.
-
- Arithmetic Integral objects and objects having the type float, double, and
- long double.
-
- Scalar Arithmetic objects and pointers to objects of any type. Also C++
- references.
-
- Aggregate Arrays, structures, and unions. Also C++ classes.
-
- Many operators cause conversions from one data type to another. Conversions
- are discussed in Implicit Type Conversions.
-
-
- ΓòÉΓòÉΓòÉ 5.3. lvalues ΓòÉΓòÉΓòÉ
-
- An lvalue is an expression that represents an object that can be examined or
- changed. A modifiable lvalue is an expression representing an object that can
- be changed. It is typically the left operand in an assignment expression. For
- example, arrays and const objects are not modifiable lvalues, but static int
- objects are.
-
- All assignment operators evaluate their right operand and assign that value to
- their left operand. The left operand must evaluate to a reference to an object.
-
- The address operator (&) requires an lvalue as an operand while the increment
- (++) and the decrement (--) operators require a modifiable lvalue as an
- operand.
-
- Examples of Lvalues
-
- Related Information
-
- Assignment Expressions
- Address &
- Dot Operator .
- Arrow Operator ->
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Lvalues ΓòÉΓòÉΓòÉ
-
- Expression Lvalue
- x = 42; x
- *ptr = newvalue; *ptr
- a++ a
-
-
- ΓòÉΓòÉΓòÉ 5.4. Primary Expressions ΓòÉΓòÉΓòÉ
-
- A primary expression can be:
-
- Identifiers
- String Literals
- C++ Scope Resolution Operator ::
- Parenthesized Expressions ( )
- Constant Expressions
- Function Calls ( )
- Array Subscript [ ] (Array Element Specification)
- Dot Operator .
- Arrow Operator ->
- C++ Runtime Type Identification Operators
-
- All primary operators have the same precedence and have left-to-right
- associativity.
-
- Related Information
-
- Expressions and Operators
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ 5.4.1. C++ Scope Resolution Operator :: ΓòÉΓòÉΓòÉ
-
- The :: (scope resolution) operator is used to qualify hidden names so that you
- can still use them. You can use the unary scope operator if a file scope name
- is hidden by an explicit declaration of the same name in a block or class. For
- example:
-
- int i = 10;
- int f(int i)
- {
- return i ? i : :: i; // return global i if local i is zero
- }
-
- You can also use the class scope operator to qualify class names or class
- member names. If a class member name is hidden, you can use it by qualifying it
- with its class name and the class scope operator. Whenever a name is followed
- by a :: operator, the name is interpreted as a class name.
-
- In the following example, the declaration of the variable X hides the class
- type X, but you can still use the static class member count by qualifying it
- with the class type X and the scope resolution operator.
-
- #include <iostream.h>
- class X
- {
- public:
- static int count;
- };
- int X::count = 10; // define static data member
- void main ()
- {
- int X = 0; // hides class type X
- cout << X::count << endl; // use static member of class X
- }
-
- The scope resolution operator is also discussed in Class Names and in Scope of
- Class Names.
-
- Related Information
-
- Class Names
- Scope of Class Names
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ 5.4.2. Parenthesized Expressions ( ) ΓòÉΓòÉΓòÉ
-
- Use parentheses to explicitly force the order of expression evaluation. The
- following expression does not contain any parentheses used for grouping
- operands and operators. The parentheses surrounding weight, zipcode are used to
- form a function call. Note how the compiler groups the operands and operators
- in the expression according to the rules for operator precedence and
- associativity:
-
-
- -discount * item + handling(weight, zipcode) < .10 * item
- | | | | | | |
- '---.---' | '-----------.-----------' '----.---'
- '----.-----' | |
- '----------.----------' |
- '-------------------------------'
-
- The following expression is similar to the previous expression, but it contains
- parentheses that change how the operands and operators are grouped:
-
-
- (-discount * (item + handling(weight, zipcode) ) ) < (.10 * item)
- | | | | | | |
- '---.---' | '----------.------------' '-----.----'
- | '--------.--------' |
- '-------.---------' |
- '---------------------------------------------'
-
- In an expression that contains both associative and commutative operators, you
- can use parentheses to specify the grouping of operands with operators. The
- parentheses in the following expression guarantee the order of grouping
- operands with the operators:
-
- x = f + (g + h);
-
- Related Information
-
- Operator Precedence and Associativity
- Function Calls ( )
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ 5.4.3. Constant Expressions ΓòÉΓòÉΓòÉ
-
- A constant expression is an expression with a value that may be determined
- during compilation and cannot be changed at runtime, it can only be evaluated.
- Constant expressions can be composed of integer constants, character constants,
- floating-point constants, and enumeration constants, address constants, and
- other constant expressions. Some constant expressions, such as a string literal
- or an address constant, are lvalues.
-
- The C and C++ languages require integral constant expressions in the following
- places:
-
- In the subscript declarator, as the description of an array bound
- After the keyword case in a switch statement
- In an enumerator, as the numeric value of an enum constant
- In a bit-field width specifier
- In the preprocessor #if statement (Enumeration constants, address
- constants, and sizeof cannot be specified in the preprocessor #if
- statement.)
- In the initializer of a file scope data definition.
-
- In all these contexts except for an initializer of a file scope data
- definition, the constant expression can contain integer, character, and
- enumeration constants, casts to integral types, and sizeof expressions.
- Function-scope static and extern declarations can be initialized with the
- address of a previously defined static or extern.
-
- In a file scope data definition, the initializer must evaluate to a constant
- or to the address of a static storage (extern or static) object (plus or minus
- an integer constant) that is defined or declared earlier in the file. The
- constant expression in the initializer can contain:
-
- integer, character, enumeration, and float constants
- casts to any type
- sizeof expressions
- unary address expressions (static objects only)
-
- Functions, class objects, pointers, and references are not allowed unless they
- occur in sizeof expressions. Comma operators and assignment operators cannot
- appear in constant expressions.
-
- Examples of Constant Expressions
-
- Related Information
-
- Arrays
- Initializers
- File Scope Data Declarations
- switch
- Enumerations
- Structures
- Conditional Compilation Directives
- sizeof (Size of an Object)
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Constant Expressions ΓòÉΓòÉΓòÉ
-
- The following examples show constants used in expressions.
-
- Expression Constant
- x = 42; 42
- extern int cost = 1000; 1000
- y = 3 * 29; 3 * 29
-
-
- ΓòÉΓòÉΓòÉ 5.4.4. Function Calls ( ) ΓòÉΓòÉΓòÉ
-
- A function call is a primary expression containing a simple type name and a
- parenthesized argument list. The argument list can contain any number of
- expressions separated by commas. It can also be empty.
-
- For example:
-
- stub()
- overdue(account, date, amount)
- notify(name, date + 5)
- report(error, time, date, ++num)
-
- The arguments are evaluated, and each formal parameter is initialized with the
- value of the corresponding argument. The semantics of argument passing are
- identical to those of assignment. Assigning a value to a formal parameter
- within the function body changes the value of the parameter within the
- function, but has no effect on the argument.
-
- The type of a function call expression is the return type of the function. The
- return value is determined by the return statement in the function definition.
- The result of a function call is an lvalue only if the function returns a
- reference. A function can call itself.
-
- If you want a function to change the value of a variable, pass a pointer to the
- variable you want changed. When a pointer is passed as a parameter, the pointer
- is copied; the object pointed to is not copied. (See Pointers.)
-
- Arguments that are arrays and functions are converted to pointers before being
- passed as function arguments.
-
- Arguments passed to nonprototyped C functions undergo conversions: type short
- or char parameters are converted to int, and float parameters to double. Use a
- cast expression for other conversions. (See Cast Expressions.)
-
- In C only, if a function definition has external linkage and a return type of
- int, calls to the function can be made before it is explicitly declared because
- an implicit declaration of extern int func(); is assumed. This is not true for
- C++.
-
- The compiler compares the data types provided by the calling function with the
- data types that the called function expects. The compiler might also perform
- type conversions if the declaration of the function is in function prototype
- format and the parameters differ from the prototype or visible at the point
- where the function is called.
-
- The order in which parameters are evaluated is not specified. Avoid such calls
- as:
-
- method(samp1, bat.proc--, bat.proc);
-
- In this example, bat.proc-- might be evaluated last, causing the last two
- arguments to be passed with the same value.
-
- Example of a Function Call
-
- Related Information
-
- Functions
- Pointers
- Cast Expressions
- Primary Expressions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a Function Call ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, main passes func two values: 5 and 7. The function
- func receives copies of these values and accesses them by the identifiers: a
- and b. The function func changes the value of a. When control passes back to
- main, the actual values of x and y are not changed. The called function func
- only receives copies of x and y, not the values themselves.
-
- *
- ************************************************************************/
-
- /**
- ** This example illustrates function calls
- **/
-
- #include <stdio.h>
-
- int main(void)
- {
- int x = 5, y = 7;
-
- func(x, y);
- printf("In main, x = %d y = %d\n", x, y);
- }
-
- void func (int a, int b)
- {
- a += b;
- printf("In func, a = %d b = %d\n", a, b);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- In func, a = 12 b = 7
- In main, x = 5 y = 7
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 5.4.5. Array Subscript [ ] (Array Element Specification) ΓòÉΓòÉΓòÉ
-
- A primary expression followed by an expression in [ ] (square brackets)
- specifies an element of an array. The expression within the square brackets is
- referred to as a subscript.
-
- The primary expression must have a pointer type, and the subscript must have
- integral type. The result of an array subscript is an lvalue.
-
- The first element of each array has the subscript 0. The expression
- contract[35] refers to the 36th element in the array contract.
-
- In a multidimensional array, you can reference each element (in the order of
- increasing storage locations) by incrementing the rightmost subscript most
- frequently.
-
- For example, the following statement gives the value 100 to each element in the
- array code[4][3][6]:
-
- for (first = 0; first <= 3; ++first)
- for (second = 0; second <= 2; ++second)
- for (third = 0; third <= 5; ++third)
- code[first][second][third] = 100;
-
- By definition, the expression:
-
- *((exp1) + (exp2))
-
- is identical to the expression:
-
- exp1[exp2]
-
- which is also identical to:
-
- exp2[exp1]
-
- Related Information
-
- Arrays
- lvalues
- Primary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.4.6. Dot Operator . ΓòÉΓòÉΓòÉ
-
- The . (dot) operator is used to access structure or C++ class members using a
- structure object. The member is specified by a primary expression, followed by
- a . (dot) operator, followed by a name. For example:
-
- roster[num].name
- roster[num].name[1]
-
- The primary expression must be an object of type class, struct or union. The
- name must be a member of that object.
-
- The value of the expression is the value of the selected member. If the primary
- expression and the name are lvalues, the expression value is also an lvalue.
-
- For more information on class members, see C++ Class Members and Friends.
-
- Related Information
-
- Arrow Operator ->
- C++ Class Members and Friends
- Unions
- Structures
- lvalues
- Primary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.4.7. Arrow Operator -> ΓòÉΓòÉΓòÉ
-
- The -> (arrow) operator is used to access structure or C++ class members using
- a pointer. A primary expression, followed by an -> (arrow) operator, followed
- by a name, designates a member of the object to which the pointer points. For
- example:
-
- roster -> name
-
- The primary expression must be a pointer to an object of type class, struct or
- union. The name must be a member of that object.
-
- The value of the expression is the value of the selected member. If the name is
- an lvalue, the expression value is also an lvalue.
-
- For more information on class members, see C++ Class Members and Friends.
-
- Related Information
-
- Dot Operator .
- C++ Class Members and Friends
- Unions
- Structures
- lvalues
- Pointers
- Primary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.5. C++ Runtime Type Identification Operators ΓòÉΓòÉΓòÉ
-
- Runtime type identification (RTTI) provides a standardized mechanism for
- determining the class of an object at run time.
-
- VisualAge for C++ support for RTTI is composed of:
-
- A dynamic_cast operator Allows type conversions that are checked at run time.
- It combines type-checking and casting in one operation by
- verifying the requested cast and performing it only if it is
- valid.
-
- A typeid operator Returns the runtime type of an object.
-
- A type_info class Describes the RTTI available and is used to define the type
- return by the typeid operator.
-
- RTTI is not a replacement for static (compile-time) checking. You should use
- virtual functions instead of RTTI wherever possible. RTTI is necessary when
- the code for the base class or the code for some of the derived classes is not
- available to users. Extending base classes provided by libraries is one
- example.
-
- Note: The I/O Stream classes do not support RTTI. The dynamic_cast and typeid
- operators will yield unpredict results when used with I/O Stream objects.
-
- See the IBM VisualAge for C++ for Windows Programming Guide for more
- information about using RTTI.
-
-
- ΓòÉΓòÉΓòÉ 5.5.1. dynamic_cast<>() ΓòÉΓòÉΓòÉ
-
- A dynamic cast expression is used to cast a base class pointer to a derived
- class pointer (referred to as downcasting.)
-
- The dynamic_cast operator makes downcasting much safer than conventional static
- casting. It obtains a pointer to an object of a derived class given a pointer
- to a base class of that object. The operator dynamic_cast returns the pointer
- only if the specific derived class actually exists. If not, it returns zero.
-
- Dynamic casts have the form:
-
- >>ΓöÇΓöÇdynamic_castΓöÇΓöÇΓöÉΓöÇΓöÇtype_nameΓöÇΓöÇ>ΓöÇΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The operator converts the expression to the desired type type_name. The
- type_name can be a pointer or a reference to a class type.
-
-
- ΓòÉΓòÉΓòÉ 5.5.1.1. Dynamic Casts with Pointers ΓòÉΓòÉΓòÉ
-
- A dynamic cast using pointers is used to get a pointer to a derived class in
- order to use some detail of the derived class that is not otherwise available.
- If the dynamic cast to a pointer type_name fails, the value of the expression
- is zero.
-
- For example,
-
- class employee {
- public:
- virtual int salary();
- };
-
- class manager : public employee {
- public:
- int salary();
- virtual int bonus();
- };
-
- In this class hierarchy, dynamic casts can be used to include the
- manager::bonus() function in the manager's salary calculation but not in the
- calculation for a regular employee. The dynamic_cast operator uses a pointer to
- the base class employee and gets a pointer to the derived class manager in
- order to use the bonus member function.
-
- void payroll::calc (employee *pe) {
- // employee salary calculation
- if (manager *pm = dynamic_cast<manager*>(pe)) {
- // use manager::bonus()
- }
- else {
- // use employee's member functions
- }
- }
-
- If pe actually points to a manager object at run time, the dynamic cast is
- successful, pm is initialized to a pointer to a manager, and the bonus function
- is used. If not, pm is initialized to zero and only the functions in the
- employee base class are used.
-
- Note: In this example, dynamic casts are needed only if the base class
- employee and its derived classes are not available to users (as in part of a
- library where it is undesirable to modify the source code.) Otherwise, adding
- new virtual functions and providing derived classes with specialized
- definitions for those functions is a better choice to solve this problem.
-
-
- ΓòÉΓòÉΓòÉ 5.5.1.2. Dynamic Casts with References ΓòÉΓòÉΓòÉ
-
- The dynamic_cast operator can also be used to cast to reference types. This is
- because C++ reference casts are similar to pointer casts: they can be used to
- cast from references to base class objects to references to derived class
- objects.
-
- In dynamic casts to reference types, type_name represents a type and expression
- represents a reference. The operator converts the expression to the desired
- type type_name&.
-
- Because there is no such thing as a zero reference, it is not possible to
- verify the success of a dynamic cast using reference types by comparing the
- result (the reference that results from the dynamic cast) with zero. A failing
- dynamic cast to a reference type throws a bad_cast exception.
-
- A dynamic cast with a reference is a good way to test for a coding assumption.
- The employee example above using reference casts is:
-
- void payroll::calc (employee &re) {
- // employee salary calculation
- try {
- manager &rm = dynamic_cast<manager&>(re);
- // use manager::bonus()
- }
- catch (bad_cast) {
- // use employee's member functions
- }
- }
-
- Note: This example is only intended to illustrate the dynamic_cast operator
- used as a test. This example does not demonstrate good programming style, since
- it uses exceptions to control execution flow. Using dynamic_cast with pointers
- as shown above is a better choice.
-
- Related Information
-
- typeid()
- Inheritance Overview
- Virtual Functions
- Classes for Runtime Type Identification
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.5.2. typeid() ΓòÉΓòÉΓòÉ
-
- The typeid operator identifies the exact type of an object given a pointer to a
- base class. It is typically used to gain access to information needed to
- perform some operation where no common interface can be assumed for every
- object manipulated by the system. For example, object I/O and database systems
- often need to perform services on objects where no virtual function is
- available to do so. The typeid operator enables this.
-
- A typeid operation has the following form:
-
- >>ΓöÇΓöÇtypeidΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇtype_nameΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇexpressionΓöÇΓöÿ
-
- The result of a typeid operation has type const type_info&.
-
- The following table summarizes the results if various typeid operations.
-
- Operand typeid Returns
- typename A reference to a type_info object that represents it.
- expression A reference to a type_info that represents the type of
- the expression.
- Reference to a polymorphic type The type_info for the complete object referred
- to.
- Pointer to a polymorphic type The dynamic type of the complete object pointed
- to. If the pointer is zero, the typeid expression
- throws the bad_typeid exception.
- Nonpolymorphic type The type_info that represents the static type of the
- expression. The expression is not evaluated.
-
- The following examples use the typeid operator in expressions that compare the
- runtime type of objects in the employee class hierarchy:
-
- // ...
- employee *pe = new manager;
- employee& re = *pe;
- // ...
- typeid(pe) == typeid(employee*) // 1. True - not a polymorphic type
- typeid(&re) == typeid(employee*) // 2. True - not a polymorphic type
- typeid(*pe) == typeid(manager) // 3. True - *pe represents a polymorphic type
- typeid(re) == typeid(manager) // 4. True - re represents the object manager
-
- typeid(pe) == typeid(manager*) // 5. False - static type of pe returned
- typeid(pe) == typeid(employee) // 6. False - static type of pe returned
- typeid(pe) == typeid(manager) // 7. False - static type of pe returned
-
- typeid(*pe) == typeid(employee) // 8. False - dynamic type of expression is manager
- typeid(re) == typeid(employee) // 9. False - re actually represents manager
- typeid(&re) == typeid(manager*) // 10. False - manager* not the static type of re
- // ...
-
- In comparison 1, pe is a pointer (i.e. not a polymorphic type); therefore, the
- expression typeid(pe) returns the static type of pe, which is equivalent to
- employee*.
-
- Similarly, re in comparison 2 represents the addess of the object referred to
- (i.e. not a polymorphic type); therefore, the expression typeid(re) returns
- the static type of re, which is a pointer to employee.
-
- The type returned by typeid represents the dynamic type of the expression only
- when the expression represents a polymorphic type, as in comparisons 3 and 4.
-
- Comparisons 5, 6, and 7 are false because it is the type of the expression
- (pe) that is examined, not the type of the object pointed to by pe.
-
- Note that these examples do not directly manipulate type_info objects. Using
- the typeid operator with builtin types requires interaction with type_info
- objects.
-
- For example:
-
- int i;
- // ...
- typeid(i) == typeid(int) // True
- typeid(8) == typeid(int) // True
- // ...
-
- The class type_info is described in Classes for Runtime Type Identification.
-
- Related Information
-
- dynamic_cast<>()
- Inheritance Overview
- Virtual Functions
- Classes for Runtime Type Identification
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.6. Unary Expressions ΓòÉΓòÉΓòÉ
-
- A unary expression contains one operand and a unary operator. All unary
- operators have the same precedence and have right-to-left associativity.
-
- As indicated in the following descriptions, the usual arithmetic conversions
- are performed on the operands of most unary expressions. See Arithmetic
- Conversions for more information.
-
- Increment ++
- Decrement - -
- Unary Plus +
- Unary Minus -
- Logical Negation !
- Bitwise Negation ~
- Address &
- Indirection *
- Cast Expressions
- sizeof (Size of an Object)
- C++ new Operator
- C++ delete Operator
- C++ throw Expressions
-
- Related Information
-
- Binary Expressions
- Expressions and Operators
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ 5.6.1. Increment ++ ΓòÉΓòÉΓòÉ
-
- The ++ (increment) operator adds 1 to the value of a scalar operand, or if the
- operand is a pointer, increments the operand by the size of the object to which
- it points. The operand receives the result of the increment operation. The
- operand must be a modifiable lvalue of arithmetic or pointer type.
-
- You can put the ++ before or after the operand. If it appears before the
- operand, the operand is incremented. Then the incremented value is used in the
- expression. If you put the ++ after the operand, the value of the operand is
- used in the expression before the operand is incremented. For example:
-
- play = ++play1 + play2++;
-
- is equivalent to the following three expressions:
-
- play1 = play1 + 1;
- play = play1 + play2;
- play2 = play2 + 1;
-
- C++ Note: C++ distinguishes between prefix and postfix forms of the increment
- operator. The result of a C++ postfix increment has the same type as the
- operand after integral promotion, but is not an lvalue. The result of a C++
- prefix increment has the same type as the operand after integral promotion, and
- is an lvalue. The C language makes no such distinction. The result in C has the
- same type as the operand after integral promotion, but is not an lvalue.
-
- Related Information
-
- Decrement - -
- Addition +
- Pointer Arithmetic
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.2. Decrement - - ΓòÉΓòÉΓòÉ
-
- The -- (decrement) operator subtracts 1 from the value of a scalar operand, or
- if the operand is a pointer, decreases the operand by the size of the object to
- which it points. The operand receives the result of the decrement operation.
- The operand must be a modifiable lvalue.
-
- You can put the -- before or after the operand. If it appears before the
- operand, the operand is decremented, and the decremented value is used in the
- expression. If the -- appears after the operand, the current value of the
- operand is used in the expression and the operand is decremented.
-
- For example:
-
- play = --play1 + play2--;
-
- is equivalent to the following three expressions:
-
- play1 = play1 - 1;
- play = play1 + play2;
- play2 = play2 - 1;
-
- C++ Note: C++ distinguishes between prefix and postfix forms of the decrement
- operator. The result of a C++ postfix decrement has the same type as the
- operand after integral promotion, but is not an lvalue. The result of a C++
- prefix decrement has the same type as the operand after integral promotion, and
- is an lvalue. The C language makes no such distinction. The result in C has the
- same type as the operand after integral promotion, but is not an lvalue.
-
- Related Information
-
- Increment ++
- Subtraction -
- Pointer Arithmetic
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.3. Unary Plus + ΓòÉΓòÉΓòÉ
-
- The + (unary plus) operator maintains the value of the operand. The operand
- can have any arithmetic type. The result is not an lvalue.
-
- The result has the same type as the operand after integral promotion.
-
- Note: Any plus sign in front of a constant is not part of the constant.
-
- Related Information
-
- Unary Minus -
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.4. Unary Minus - ΓòÉΓòÉΓòÉ
-
- The - (unary minus) operator negates the value of the operand. The operand can
- have any arithmetic type. The result is not an lvalue.
-
- For example, if quality has the value 100, -quality has the value -100.
-
- The result has the same type as the operand after integral promotion.
-
- Note: Any minus sign in front of a constant is not part of the constant.
-
- Related Information
-
- Unary Plus +
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.5. Logical Negation ! ΓòÉΓòÉΓòÉ
-
- The ! (logical negation) operator determines whether the operand evaluates to 0
- (false) or nonzero (true). The expression yields the value 1 (true) if the
- operand evaluates to 0, and yields the value 0 (false) if the operand evaluates
- to a nonzero value. The operand must have a scalar data type, but the result of
- the operation has always type int and is not an lvalue.
-
- The following two expressions are equivalent:
-
- !right;
- right == 0;
-
- Related Information
-
- Equality == !=
- Relational < > <= >=
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.6. Bitwise Negation ~ ΓòÉΓòÉΓòÉ
-
- The ~ (bitwise negation) operator yields the bitwise complement of the operand.
- In the binary representation of the result, every bit has the opposite value of
- the same bit in the binary representation of the operand. The operand must have
- an integral type. The result has the same type as the operand but is not an
- lvalue.
-
- Suppose x represents the decimal value 5. The 32-bit binary representation of x
- is:
-
- 00000000000000000000000000000101
-
- The expression ~x yields the following result, represented here as a 32-bit
- binary number:
-
- 11111111111111111111111111111010
-
- The 32-bit binary representation of ~0 is:
-
- 11111111111111111111111111111111
-
- Related Information
-
- Bitwise Left and Right Shift << >>
- Bitwise AND &
- Bitwise Exclusive OR ^
- Bitwise Inclusive OR |
- Unary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.6.7. Address & ΓòÉΓòÉΓòÉ
-
- The & (address) operator yields a pointer to its operand. The operand must be
- an lvalue, a function designator, or a qualified name. It cannot be a bit
- field, nor can it have the storage class register.
-
- If the operand is an lvalue or function, the resulting type is a pointer to the
- expression type. For example, if the expression has type int, the result is a
- pointer to an object having type int.
-
- If the operand is a qualified name and the member is not static, the result is
- a pointer to a member of class and has the same type as the member. The result
- is not an lvalue.
-
- If p_to_y is defined as a pointer to an int and y as an int, the following
- expression assigns the address of the variable y to the pointer p_to_y:
-
- p_to_y = &y;
-
- C++ Note: You can use the & operator with overloaded functions only in an
- initialization or assignment where the left side uniquely determines which
- version of the overloaded function is used. For more information, see
- Overloading Functions.
-
- Related Information
-
- Pointers
- lvalues
- register Storage Class Specifier
- Overloading Functions
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.6.8. Indirection * ΓòÉΓòÉΓòÉ
-
- The * (indirection) operator determines the value referred to by the
- pointer-type operand. The operand cannot be a pointer to an incomplete type.
- The operation yields an lvalue or a function designator if the operand points
- to a function. Arrays and functions are converted to pointers.
-
- The type of the operand determines the type of the result. For example, if the
- operand is a pointer to an int, the result has type int.
-
- Do not apply the indirection operator to any pointer that contains an address
- that is not valid, such as NULL. The result is not defined.
-
- If p_to_y is defined as a pointer to an int and y as an int, the expressions:
-
- p_to_y = &y;
- *p_to_y = 3;
-
- cause the variable y to receive the value 3.
-
- Related Information
-
- Pointers
- lvalues
- Functions
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.6.9. Cast Expressions ΓòÉΓòÉΓòÉ
-
- The cast operator is used for explicit type conversions. It converts the value
- of the operand to a specified data type and performs the necessary conversions
- to the operand for the type.
-
- For C, the operand must be scalar and the type must be either scalar or void.
- For C++, the operand can have class type. If the operand has class type, it can
- be cast to any type for which the class has a user-defined conversion function.
- User-defined conversion functions are described in Conversion Functions.
-
- The result of a cast is not an lvalue unless the cast is to a reference type.
- When you cast to a reference type, no user-defined conversions are performed
- and the result is an lvalue.
-
- There are two types of casts that take one argument:
-
- C-style casts, with the format (X)a. These are the only casts allowed in
- C.
- function-style casts with one argument, such as X(a). These are allowed
- in C++ only.
-
- Both types of casts convert the argument a to the type X. In C++, they can
- invoke a constructor, if the target type is a class, or they can invoke a
- conversion function, if the source type is a class. They can be ambiguous if
- both conditions hold.
-
- A function-style cast with no arguments, such as X(), creates a temporary
- object of type X. If X is a class with constructors, the default constructor
- X::X() is called.
-
- A function-style cast with more than one argument, such as X(a,b), creates a
- temporary object of type X. This object must be a class with a constructor
- that takes two arguments of types compatible with the types of a and b. The
- constructor is called with a and b as arguments.
-
- Related Information
-
- Implicit Type Conversions
- Conversion by Constructor
- Conversion Functions
- Type Specifiers
-
-
- ΓòÉΓòÉΓòÉ 5.6.10. sizeof (Size of an Object) ΓòÉΓòÉΓòÉ
-
- The sizeof operator yields the size in bytes of the operand. Types cannot be
- defined in a sizeof expression. The sizeof operation cannot be performed on
-
- A bit field
- A function
- An undefined structure or class
- An incomplete type (such as void)
-
- The operand can be the parenthesized name of a type or expression.
-
- The compiler must be able to evaluate the size at compile time. The expression
- is not evaluated; there are no side effects. For example, the value of b is 5
- from initialization to the end of program runtime:
-
- #include <stdio.h>
-
- int main(void){
- int b = 5;
- sizeof(b++);
- }
-
- The result is an integer constant.
-
- The size of a char object is the size of a byte. For example, if a variable x
- has type char, the expression sizeof(x) always evaluates to 1.
-
- The result of a sizeof operation has type size_t, which is an unsigned
- integral type defined in the <stddef.h> header.
-
- The size of an object is determined on the basis of its definition. The sizeof
- operator does not perform any conversions. If the operand contains operators
- that perform conversions, the compiler does take these conversions into
- consideration. The following expression causes the usual arithmetic
- conversions to be performed. The result of the expression x + 1 has type int
- (if x has type char, short, or int or any enumeration type) and is equivalent
- to sizeof(int):
-
- sizeof (x + 1);
-
- Except in preprocessor directives, you can use a sizeof expression wherever an
- integral constant is required. One of the most common uses for the sizeof
- operator is to determine the size of objects that are referred to during
- storage allocation, input, and output functions.
-
- Another use of sizeof is in porting code across platforms. You should use the
- sizeof operator to determine the size that a data type represents. For
- example:
-
- sizeof(int);
-
- C++ Notes: The result of a sizeof expression depends on the type it is
- applied to:
-
- An array The result is the total number of bytes in the array. For example,
- in an array with 10 elements, the size is equal to 10 times the
- size of a single element. The compiler does not convert the array
- to a pointer before evaluating the expression.
-
- A class The result is always nonzero, and is equal to the number of bytes
- in an object of that class including any padding required for
- placing class objects in an array.
-
- A reference The result is the size of the referenced object.
-
- Related Information
-
- Constant Expressions
- Implicit Type Conversions
- Type Specifiers
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.6.11. C++ new Operator ΓòÉΓòÉΓòÉ
-
- The new operator provides dynamic storage allocation. The syntax for an
- allocation expression containing the new operator is:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇnewΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇ(type)ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ>
- ΓööΓöÇ::ΓöÇΓöÿ ΓööΓöÇ(argument_list)ΓöÇΓöÿ ΓööΓöÇnew_typeΓöÇΓöÿ
- >ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÿ
- ΓööΓöÇinitial_valueΓöÇΓöÿ
-
- If you prefix new with the scope resolution operator (::), the global operator
- new() is used. If you specify an argument_list, the overloaded new operator
- that corresponds to that argument_list is used. The type is an existing
- built-in or user-defined type. A new_type is a type that has not already been
- defined and can include type specifiers and declarators.
-
- An allocation expression containing the new operator is used to find storage in
- free store for the object being created. The new expression returns a pointer
- to the object created and can be used to initialize the object. If the object
- is an array, a pointer to the initial element is returned.
-
- You can use the routine set_new_handler() to change the default behavior of
- new. You can also use the /Tm option to enable a debug version of new, as
- described in Debug Versions of new and delete.
-
- You cannot use the new operator to allocate function types, void, or incomplete
- class types because these are not object types. However, you can allocate
- pointers to functions with the new operator. You cannot create a reference with
- the new operator.
-
- When the object being created is an array, only the first dimension can be a
- general expression. All subsequent dimensions must be constant integral
- expressions. The first dimension can be a general expression even when an
- existing type is used. You can create an array with zero bounds with the new
- operator. For example:
-
- char * c = new char[0];
-
- In this case, a pointer to a unique object is returned.
-
- An object created with operator new() or operator new[]() exists until the
- operator delete() or operator delete[]() is called to deallocate the object's
- memory, or until program ends.
-
- If parentheses are used within a new_type, parentheses should also surround the
- new_type to prevent syntax errors.
-
- Example of Allocating Storage with new()
-
- The type of the object being created cannot contain class declarations,
- enumeration declarations, or const or volatile types. It can contain pointers
- to const or volatile objects.
-
- For example, const char* is allowed, but char* const is not.
-
- Additional arguments can be supplied to new by using the argument_list, also
- called the placement syntax. If placement arguments are used, a declaration of
- operator new() or operator new[]() with these arguments must exist. For
- example:
-
- #include <stddef.h>
- class X
- {
- public:
- void* operator new(size_t,int, int){ /* ... */ }
- };
- void main ()
- {
- X* ptr = new(1,2) X;
- }
-
- Additional information is provided on:
-
- Member Functions and the Global operator new() and operator new[]()
- Initializing Objects Created with the new Operator
-
- Related Information
-
- set_new_handler() - Set Behavior for new Failure
- Overloaded new and delete
- Debug Versions of new and delete
- Constructors and Destructors Overview
- Free Store
- C++ delete Operator
- Unary Expressions
- /Tm option
-
-
- ΓòÉΓòÉΓòÉ 5.6.11.1. Member Functions and the Global operator new() and operator new[]() ΓòÉΓòÉΓòÉ
-
- When an object of a class type is created with the new operator, the member
- operator new() function (for objects that are not arrays) or the member
- operator new[]() function (for arrays of any number of dimensions) is
- implicitly called. The first argument is the amount of space requested.
-
- The following rules determine which storage allocation function is used:
-
- 1. If your own operator new[]() exists, the object is an array, and the ::
- (scope resolution) operator is not used, your operator new[]() is used.
-
- 2. If you have not defined an operator new[]() function, the global
- ::operator new[]() function defined in <new.h> is used. The allocation
- expression of the form ::operator new[]() ensures that the global new
- operator is called, rather than your class member operator.
-
- 3. If your own operator new() exists, and the object is not an array, and
- the :: operator is not used, your operator new() is used.
-
- 4. If you have not defined an operator new() function, the global ::operator
- new() function defined in <new.h> is used. The allocation expression of
- the form ::operator new() ensures that the global new operator is called,
- rather than your class member operator.
-
- When a nonclass object is created with the new operator, the global ::operator
- new() is used.
-
- The order of evaluation of a call to an operator new() is undefined in the
- evaluation of arguments to constructors. If operator new() returns 0, the
- arguments to a constructor may or may not have been evaluated.
-
-
- ΓòÉΓòÉΓòÉ 5.6.11.2. Initializing Objects Created with the new Operator ΓòÉΓòÉΓòÉ
-
- You can initialize objects created with the new operator in several ways. For
- nonclass objects, or for class objects without constructors, a new initializer
- expression can be provided in a new expression by specifying ( expression ) or
- (). For example:
-
- double* pi = new double(3.1415926);
- int* score = new int(89);
- float* unknown = new float();
-
- If a class has a constructor, the new initializer must be provided when any
- object of that class is allocated. The arguments of the new initializer must
- match the arguments of a class constructor, unless the class has a default
- constructor.
-
- You cannot specify an initializer for arrays. You can initialize an array of
- class objects only if the class has a default constructor. The constructor is
- called to initialize each array element (class object).
-
- Initialization using the new initializer is performed only if new successfully
- allocates storage.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Allocating Storage with new() ΓòÉΓòÉΓòÉ
-
- /***********************************************************************
- *
-
- In the following example, storage is allocated for an array of pointers to
- functions:
-
- *
- ************************************************************************/
-
- void f();
- void g();
- void main()
- {
- void (**p)(), (**q)();
- // declare p and q as pointers to pointers to void functions
- p = new (void (*[3])());
- // p now points to an array of pointers to functions
- q = new void(*[3])(); // error
- // error - bound as 'q = (new void) (*[3])();'
- p[0] = f; // p[0] to point to function f
- q[2] = g; // q[2] to point to function g
- p[0](); // call f()
- q[2](); // call g()
- }
-
- /************************************************************************
- *
-
- However, the second use of new causes an erroneous binding of q = (new void)
- (*[3])().
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 5.6.11.3. set_new_handler() - Set Behavior for new Failure ΓòÉΓòÉΓòÉ
-
- When the new operator creates a new object, it calls the operator new() or
- operator new[]() function to obtain the needed storage.
-
- When new cannot allocate storage to create a new object, it calls a new handler
- function if one has been installed by a call to set_new_handler(). The
- set_new_handler() function is defined in <new.h>. Use it to call a new handler
- you have defined or the default new handler.
-
- The set_new_handler() function has the prototype:
-
- typedef void(*PNH)();
- PNH set_new_handler(PNH);
-
- set_new_handler() takes as an argument a pointer to a function (the new
- handler), which has no arguments and returns void. It returns a pointer to the
- previous new handler function.
-
- If you do not specify your own set_new_handler() function, new returns the NULL
- pointer.
-
- The _set_mt_new_handler() function behaves exactly the same way as
- set_new_handler(), except that it only affects the current thread. When a new
- handler function needs to be called, the code first checks for a thread new
- handler. If one has been registered, it is called. If not, the new handler
- registered with set_new_handler() is called.
-
- Example of set_new_handler()
-
- Related Information
-
- C++ new Operator
- Member Functions and the Global operator new()
- Initializing Objects Created with the new Operator
- Overloaded new and delete
- Constructors and Destructors Overview
- Free Store
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of set_new_handler() ΓòÉΓòÉΓòÉ
-
- The following program fragment shows how you could use set_new_handler() to
- return a message if the new operator cannot allocate storage:
-
- #include <iostream.h>
- #include <new.h>
- void no_storage()
- {
- cerr << "Operator new failed: no storage is available.\n";
- exit(1);
- }
- main()
- {
- set_new_handler(&no_storage);
- // Rest of program ...
- }
-
- If the program fails because new cannot allocate storage, the program exits
- with the message:
-
- Operator new failed: no storage is available.
-
-
- ΓòÉΓòÉΓòÉ 5.6.12. C++ delete Operator ΓòÉΓòÉΓòÉ
-
- The delete operator destroys the object created with new by deallocating the
- memory associated with the object.
-
- The delete operator has a void return type. It has the syntax:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇdeleteΓöÇΓöÇobject_pointerΓöÇΓöÇ><
- ΓööΓöÇ::ΓöÇΓöÿ
-
- For example: delete myobj;
-
- The operand of delete must be a pointer returned by new, and cannot be a
- pointer to constant. If an attempt to create an object with new fails, the
- pointer returned by new will have a zero value, but it can still be used with
- delete. Deleting a null pointer has no effect.
-
- The delete[] operator frees storage allocated for array objects created with
- new[]. The delete operator frees storage allocated for individual objects
- created with new.
-
- It has the syntax:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇdeleteΓöÇΓöÇ[ΓöÇΓöÇ]ΓöÇΓöÇarrayΓöÇΓöÇ><
- ΓööΓöÇ::ΓöÇΓöÿ
-
- For example: delete [] myarray;
-
- The result of deleting an array object with delete is undefined, as is deleting
- an individual object with delete[]. The array dimensions do not need to be
- specified with delete[].
-
- The results of attempting to access a deleted object are undefined because the
- deletion of an object can change its value.
-
- If a destructor has been defined for a class, delete invokes that destructor.
- Whether a destructor exists or not, delete frees the storage pointed to by
- calling the function operator delete() of the class if one exists.
-
- The global ::operator delete() is used if:
-
- The class has no operator delete().
- The object is of a nonclass type.
- The object is deleted with the ::delete expression. For example:
- ::delete p;
-
- The global ::operator delete[]() is used if:
-
- The class has no operator delete[]()
- The object is of a nonclass type
- The object is deleted with the ::delete[] expression.
-
- The default global operator delete() only frees storage allocated by the
- default global operator new(). The default global operator delete[]() only
- frees storage allocated for arrays by the default global operator new[]().
-
- You can also use the /Tm compiler option to enable a debug version of the
- delete operator, as described in Debug Versions of new and delete.
-
- Related Information
-
- Overloaded new and delete
- Debug Versions of new and delete
- Constructors and Destructors Overview
- Free Store
- C++ new Operator
- Unary Expressions
- /Tm option
-
-
- ΓòÉΓòÉΓòÉ 5.6.13. C++ throw Expressions ΓòÉΓòÉΓòÉ
-
- A throw expression is used to throw exceptions to C++ exception handlers. It
- causes control to be passed out of the block enclosing the throw statement to
- the first C++ exception handler whose catch argument matches the throw
- expression. A throw expression is a unary expression of type void.
-
- For more information on the throw expression, see C++ Exception Handling.
-
- Related Information
-
- C++ Exception Handling
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.7. Binary Expressions ΓòÉΓòÉΓòÉ
-
- A binary expression contains two operands separated by one operator.
-
- Not all binary operators have the same precedence. The table in the section
- Operator Precedence and Associativity shows the order of precedence among
- operators. All binary operators have left-to-right associativity.
-
- The order in which the operands of most binary operators are evaluated is not
- specified. To ensure correct results, avoid creating binary expressions that
- depend on the order in which the compiler evaluates the operands.
-
- As indicated in the following descriptions, the usual arithmetic conversions
- are performed on the operands of most binary expressions. See Arithmetic
- Conversions for more information.
-
- Multiplication *
- Division /
- Remainder %
- Addition +
- Subtraction -
- Bitwise Left and Right Shift << >>
- Relational < > <= >=
- Equality == !=
- Bitwise AND &
- Bitwise Exclusive OR ^
- Bitwise Inclusive OR |
- Logical AND &&
- Logical OR ||
- C++ Pointer to Member Operators .* ->*
-
- Related Information
-
- Unary Expressions
- Expressions and Operators
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ 5.7.1. Multiplication * ΓòÉΓòÉΓòÉ
-
- The * (multiplication) operator yields the product of its operands. The
- operands must have an arithmetic type. The result is not an lvalue.
-
- Because the multiplication operator has both associative and commutative
- properties, the compiler can rearrange the operands in an expression that
- contains more than one multiplication operator. For example, the expression:
-
- sites * number * cost
-
- can be interpreted in any of the following ways:
-
- (sites * number) * cost
- sites * (number * cost)
- (cost * sites) * number
-
- Related Information
-
- Division /
- Remainder %
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.2. Division / ΓòÉΓòÉΓòÉ
-
- The / (division) operator yields the quotient of its operands. The operands
- must have an arithmetic type. The result is not an lvalue.
-
- If both operands are positive integers and the operation produces a remainder,
- the remainder is ignored. For example, expression 7 / 4 yields the value 1
- (rather than 1.75 or 2). On all IBM C and C++ compilers, if either operand is
- negative, the result is rounded towards zero.
-
- The result is undefined if the second operand evaluates to 0.
-
- Related Information
-
- Multiplication *
- Remainder %
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.3. Remainder % ΓòÉΓòÉΓòÉ
-
- The % (remainder) operator yields the remainder from the division of the left
- operand by the right operand. For example, the expression 5 % 3 yields 2. The
- result is not an lvalue.
-
- Both operands must have an integral type. If the right operand evaluates to 0,
- the result is undefined. If either operand has a negative value, the result is
- such that the following expression always yields the value of a if b is not 0
- and a/b is representable:
-
- ( a / b ) * b + a % b;
-
- The sign of the remainder is the same as the sign of the quotient. Related
- Information
-
- Multiplication *
- Division /
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.4. Addition + ΓòÉΓòÉΓòÉ
-
- The + (addition) operator yields the sum of its operands. Both operands must
- have an arithmetic type, or one operand must be a pointer to an object type and
- the other operand must have an integral type.
-
- When both operands have an arithmetic type, the usual arithmetic conversions on
- the operands are performed. The result has the type produced by the conversions
- on the operands and is not an lvalue.
-
- A pointer to an object in an array can be added to a value having integral
- type. The result is a pointer of the same type as the pointer operand. The
- result refers to another element in the array, offset from the original element
- by the amount specified by the integral value. If the resulting pointer points
- to storage outside the array, other than the first location outside the array,
- the result is undefined. The compiler does not provide boundary checking on the
- pointers.
-
- Related Information
-
- Pointers
- Unary Plus +
- Subtraction -
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.5. Subtraction - ΓòÉΓòÉΓòÉ
-
- The - (subtraction) operator yields the difference of its operands. Both
- operands must have an arithmetic type, or the left operand must have a pointer
- type and the right operand must have the same pointer type or an integral type.
- You cannot subtract a pointer from an integral value.
-
- When both operands have an arithmetic type, the usual arithmetic conversions on
- the operands are performed. The result has the type produced by the conversions
- on the operands and is not an lvalue.
-
- When the left operand is a pointer and the right operand has an integral type,
- the compiler converts the value of the right to an address offset. The result
- is a pointer of the same type as the pointer operand.
-
- If both operands are pointers to the same type, the compiler converts the
- result to an integral type that represents the number of objects separating the
- two addresses. Behavior is undefined if the pointers do not refer to objects in
- the same array.
-
- Related Information
-
- Pointers
- Unary Minus -
- Addition +
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.6. Bitwise Left and Right Shift << >> ΓòÉΓòÉΓòÉ
-
- The bitwise shift operators move the bit values of a binary object. The left
- operand specifies the value to be shifted. The right operand specifies the
- number of positions that the bits in the value are to be shifted. The result is
- not an lvalue. Both operands have the same precedence and are left-to-right
- associative.
-
- The << (bitwise left shift) operator indicates the bits are to be shifted to
- the left. The >> (bitwise right shift) operator indicates the bits are to be
- shifted to the right.
-
- Each operand must have an integral type. The compiler performs integral
- promotions on the operands. Then the right operand is converted to type int.
- The result has the same type as the left operand (after the arithmetic
- conversions).
-
- The right operand should not have a negative value or a value that is greater
- than or equal to the width in bits of the expression being shifted. The result
- of bitwise shifts on such values is unpredictable.
-
- If the right operand has the value 0, the result is the value of the left
- operand (after the usual arithmetic conversions).
-
- The << operator fills vacated bits with zeros. For example, if left_op has the
- value 4019, the bit pattern (in 32-bit format) of left_op is:
-
- 00000000000000000000111110110011
-
- The expression left_op << 3 yields:
-
- 00000000000000000111110110011000
-
- If the left operand has an unsigned type, the >> operator fills vacated bits
- with zeros. Otherwise, the compiler fills the vacated bits of a signed value
- with a copy of the value's sign bit.
-
- For example, if left_op has the value -25, the bit pattern (in 32-bit format)
- of left_op is:
-
- 11111111111111111111111111100111
-
- The expression left_op >> 3 yields:
-
- 11111111111111111111111111111100
-
- Related Information
-
- Bitwise Negation ~
- Bitwise AND &
- Bitwise Exclusive OR ^
- Bitwise Inclusive OR |
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.7. Relational < > <= >= ΓòÉΓòÉΓòÉ
-
- The relational operators compare two operands and determine the validity of a
- relationship. If the relationship stated by the operator is true, the value of
- the result is 1. If false, the value of the result is 0. The result is not an
- lvalue.
-
- The following table describes the four relational operators:
-
- Operator Usage
-
- < Indicates whether the value of the left operand is less than the
- value of the right operand.
-
- > Indicates whether the value of the left operand is greater than the
- value of the right operand.
-
- <= Indicates whether the value of the left operand is less than or
- equal to the value of the right operand.
-
- >= Indicates whether the value of the left operand is greater than or
- equal to the value of the right operand.
-
- Both operands must have arithmetic types or be pointers to the same type. The
- result has type int. If the operands have arithmetic types, the usual
- arithmetic conversions on the operands are performed.
-
- When the operands are pointers, the result is determined by the locations of
- the objects to which the pointers refer. If the pointers do not refer to
- objects in the same array, the result is not defined.
-
- A pointer can be compared to a constant expression that evaluates to 0. You
- can also compare a pointer to a pointer of type void*. The pointer is
- converted to a pointer of type void*.
-
- If two pointers refer to the same object, they are considered equal. If two
- pointers refer to nonstatic members of the same object, the pointer to the
- object declared later has the higher address value. If two pointers refer to
- data members of the same union, they have the same address value.
-
- If two pointers refer to elements of the same array, or to the first element
- beyond the last element of an array, the pointer to the element with the
- higher subscript value has the higher address value.
-
- You can only compare members of the same object with relational operators.
-
- Relational operators have left-to-right associativity. For example, the
- expression:
-
- a < b <= c
-
- is interpreted as:
-
- (a < b) <= c
-
- If the value of a is less than the value of b, the first relationship is true
- and yields the value 1. The compiler then compares the value 1 with the value
- of c.
-
- Related Information
-
- Equality == !=
- Logical Negation !
- Pointers
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.8. Equality == != ΓòÉΓòÉΓòÉ
-
- The equality operators, like the relational operators, compare two operands for
- the validity of a relationship. The equality operators, however, have a lower
- precedence than the relational operators. If the relationship stated by an
- equality operator is true, the value of the result is 1. Otherwise, the value
- of the result is 0.
-
- The following table describes the two equality operators:
-
- Operator Usage
-
- == Indicates whether the value of the left operand is equal to the
- value of the right operand.
-
- != Indicates whether the value of the left operand is not equal to the
- value of the right operand.
-
- Both operands must have arithmetic types or be pointers to the same type, or
- one operand must have a pointer type and the other operand must be a pointer
- to void or NULL. The result has type int.
-
- If the operands have arithmetic types, the usual arithmetic conversions on the
- operands are performed. If the operands are pointers, the result is determined
- by the locations of the objects to which the pointers refer.
-
- If one operand is a pointer and the other operand is an integer having the
- value 0, the == expression is true only if the pointer operand evaluates to
- NULL. The != operator evaluates to true if the pointer operand does not
- evaluate to NULL.
-
- You can also use the equality operators to compare pointers to members that
- are of the same type but do not belong to the same object.
-
- Note: The equality operator (==) should not be confused with the assignment
- (=) operator.
-
- For example,
-
- if(x == 3) evaluates to 1 if x is equal to three. Equality tests like this
- should be coded with spaces between the operator and the
- operands to prevent unintentional assignments.
-
- while
- if(x = 3) is taken to be true because (x = 3) evaluates to a non-zero
- value (3). The expression also assigns the value 3 to x.
-
- Related Information
-
- Relational < > <= >=
- Logical Negation !
- Pointers
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.9. Bitwise AND & ΓòÉΓòÉΓòÉ
-
- The & (bitwise AND) operator compares each bit of its first operand to the
- corresponding bit of the second operand. If both bits are 1's, the
- corresponding bit of the result is set to 1. Otherwise, it sets the
- corresponding result bit to 0.
-
- Both operands must have an integral type. The usual arithmetic conversions on
- each operand are performed. The result has the same type as the converted
- operands.
-
- Because the bitwise AND operator has both associative and commutative
- properties, the compiler can rearrange the operands in an expression that
- contains more than one bitwise AND operator.
-
- The following example shows the values of a, b, and the result of a & b
- represented as 32-bit binary numbers:
-
- bit pattern of a 00000000000000000000000001011100
- bit pattern of b 00000000000000000000000000101110
- bit pattern of a & b 00000000000000000000000000001100
-
- Note: The bitwise AND (&) should not be confused with the logical AND. (&&)
- operator. For example,
-
- 1 & 4 evaluates to 0
- while
- 1 && 4 evaluates to 1
-
- Related Information
-
- Bitwise Exclusive OR ^
- Bitwise Inclusive OR |
- Logical AND &&
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.10. Bitwise Exclusive OR ^ ΓòÉΓòÉΓòÉ
-
- The bitwise exclusive OR operator compares each bit of its first operand to the
- corresponding bit of the second operand. If both bits are 1's or both bits are
- 0's, the corresponding bit of the result is set to 0. Otherwise, it sets the
- corresponding result bit to 1.
-
- Both operands must have an integral type. The usual arithmetic conversions on
- each operand are performed. The result has the same type as the converted
- operands and is not an lvalue.
-
- Because the bitwise exclusive OR operator has both associative and commutative
- properties, the compiler can rearrange the operands in an expression that
- contains more than one bitwise exclusive OR operator even when the
- sub-expressions are explicitly grouped with parentheses.
-
- The following example shows the values of a, b, and the result of a ^ b
- represented as 32-bit binary numbers:
-
- bit pattern of a 00000000000000000000000001011100
- bit pattern of b 00000000000000000000000000101110
- bit pattern of a ^ b 00000000000000000000000001110010
-
- Related Information
-
- Bitwise Inclusive OR |
- Bitwise AND &
- Logical OR ||
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.11. Bitwise Inclusive OR | ΓòÉΓòÉΓòÉ
-
- The | (bitwise inclusive OR) operator compares the values (in binary format) of
- each operand and yields a value whose bit pattern shows which bits in either of
- the operands has the value 1. If both of the bits are 0, the result of that bit
- is 0; otherwise, the result is 1.
-
- Both operands must have an integral type. The usual arithmetic conversions on
- each operand are performed. The result has the same type as the converted
- operands and is not an lvalue.
-
- Because the bitwise inclusive OR operator has both associative and commutative
- properties, the compiler can rearrange the operands in an expression that
- contains more than one bitwise inclusive OR operator even when the
- subexpressions are explicitly grouped with parentheses.
-
- The following example shows the values of a, b, and the result of a | b
- represented as 32-bit binary numbers:
-
- bit pattern of a 00000000000000000000000001011100
- bit pattern of b 00000000000000000000000000101110
- bit pattern of a | b 00000000000000000000000001111110
-
- Note: The bitwise OR (|) should not be confused with the logical OR (||)
- operator. For example,
-
- 1 | 4 evaluates to 5
- while
- 1 || 4 evaluates to 1
-
- Related Information
-
- Bitwise Exclusive OR ^
- Bitwise AND &
- Logical OR ||
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.12. Logical AND && ΓòÉΓòÉΓòÉ
-
- The && (logical AND) operator indicates whether both operands have a nonzero
- value. If both operands have nonzero values, the result has the value 1.
- Otherwise, the result has the value 0.
-
- Both operands must have a scalar type. The usual arithmetic conversions on each
- operand are performed. The result has type int and is not an lvalue.
-
- Unlike the & (bitwise AND) operator, the && operator guarantees left-to-right
- evaluation of the operands. If the left operand evaluates to 0, the right
- operand is not evaluated.
-
- The following examples show how the expressions that contain the logical AND
- operator are evaluated:
-
- Expression Result
- 1 && 0 0
- 1 && 4 1
- 0 && 0 0
-
- The following example uses the logical AND operator to avoid division by zero:
-
- (y != 0) && (x / y)
-
- The expression x / y is not evaluated when y != 0 evaluates to 0.
-
- Note: The logical AND (&&) should not be confused with the bitwise AND (&)
- operator. For example:
-
- 1 && 4 evaluates to 1
- while
- 1 & 4 evaluates to 0
-
- Related Information
-
- Logical OR ||
- Bitwise AND &
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.13. Logical OR || ΓòÉΓòÉΓòÉ
-
- The || (logical OR) operator indicates whether either operand has a nonzero
- value. If either operand has a nonzero value, the result has the value 1.
- Otherwise, the result has the value 0.
-
- Both operands must have a scalar type. The usual arithmetic conversions on each
- operand are performed. The result has type int and is not an lvalue.
-
- Unlike the | (bitwise inclusive OR) operator, the || operator guarantees
- left-to-right evaluation of the operands. If the left operand has a nonzero
- value, the right operand is not evaluated.
-
- The following examples show how expressions that contain the logical OR
- operator are evaluated:
-
- Expression Result
- 1 || 0 1
- 1 || 4 1
- 0 || 0 0
-
- The following example uses the logical OR operator to conditionally increment
- y:
-
- ++x || ++y;
-
- The expression ++y is not evaluated when the expression ++x evaluates to a
- nonzero quantity.
-
- Note: The logical OR (||) should not be confused with the bitwise OR (|)
- operator. For example:
-
- 1 || 4 evaluates to 1
- while
- 1 | 4 evaluates to 5
-
- Related Information
-
- Logical AND &&
- Bitwise Inclusive OR |
- Binary Expressions
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ 5.7.14. C++ Pointer to Member Operators .* ->* ΓòÉΓòÉΓòÉ
-
- The .* operator is used to dereference pointers to class members. The first
- operand must be a class type. If the type of the first operand is class type T,
- or is a class that has been derived from class type T, the second operand must
- be a pointer to a member of a class type T.
-
- The ->* operator is also used to dereference pointers to class members. The
- first operand must be a pointer to a class type. If the type of the first
- operand is a pointer to class type T, or is a pointer to a class derived from
- class type T, the second operand must be a pointer to a member of class type T.
-
- The .* and ->* operators bind the second operand to the first, resulting in an
- object or function of the type specified by the second operand.
-
- If the result of.* or ->* is a function, you can only use the result as the
- operand for the ( ) (function call) operator. If the second operand is an
- lvalue, the result of .* or ->* is an lvalue.
-
- For more information on pointer to member operators, see Pointers to Members.
-
- Related Information
-
- Pointers to Members
- Pointers
- C++ Classes
- Binary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.8. Conditional Expressions ΓòÉΓòÉΓòÉ
-
- A conditional expression is a compound expression that contains a condition
- (operand{1}), an expression to be evaluated if the condition has a nonzero
- value (operand{2}), and an expression to be evaluated if the condition has the
- value 0 (operand{3}).
-
- Conditional expressions have right-to-left associativity. The left operand is
- evaluated first, and then only one of the remaining two operands is evaluated.
-
- The conditional expression contains one two-part operator. The ? symbol
- follows the condition, and the : symbol appears between the two action
- expressions. All expressions that occur between the ? and : are treated as one
- expression.
-
- The first operand must have a scalar type. The type of the second and third
- operands must be one of the following:
-
- An arithmetic type
- A compatible pointer, structure, or union type
- void.
-
- The second and third operands can also be a pointer or a null pointer
- constant.
-
- Two objects are compatible when they have the same type but not necessarily
- the same type qualifiers (volatile, const, or _Packed). Pointer objects are
- compatible if they have the same type or are pointers to void.
-
- The first operand is evaluated, and its value determines whether the second or
- third operand is evaluated:
-
- If the value is not equal to 0, the second operand is evaluated.
- If the value is equal to 0, the third operand is evaluated.
- The result is the value of the second or third operand.
-
- If the second and third expressions evaluate to arithmetic types, the usual
- arithmetic conversions are performed on the values. The types of the second
- and third operands determine the type of the result as shown in the following
- tables.
-
-
- ΓòÉΓòÉΓòÉ 5.8.1. Type of Conditional C Expressions ΓòÉΓòÉΓòÉ
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé TYPE OF ONE OPERAND Γöé TYPE OF OTHER OPERAND Γöé TYPE OF RESULT Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Arithmetic Γöé Arithmetic Γöé Arithmetic type after Γöé
- Γöé Γöé Γöé usual arithmetic con- Γöé
- Γöé Γöé Γöé versions Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Structure or union type Γöé Compatible structure or Γöé Structure or union type Γöé
- Γöé Γöé union type Γöé with all the qualifiers Γöé
- Γöé Γöé Γöé on both operands Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé VOID Γöé VOID Γöé VOID Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Pointer to compatible Γöé Pointer to compatible Γöé Pointer to type with Γöé
- Γöé type Γöé type Γöé all the qualifiers Γöé
- Γöé Γöé Γöé specified for the type Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Pointer to type Γöé "NULL" pointer (the con- Γöé Pointer to type Γöé
- Γöé Γöé stant "0") Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Pointer to object or Γöé Pointer to VOID Γöé Pointer to VOID with Γöé
- Γöé incomplete type Γöé Γöé all the qualifiers Γöé
- Γöé Γöé Γöé specified for the type Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 5.8.2. Type of Conditional C++ Expressions ΓòÉΓòÉΓòÉ
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé TYPE OF ONE OPERAND Γöé TYPE OF OTHER OPERAND Γöé TYPE OF RESULT Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Reference to type Γöé Reference to type Γöé Reference after usual Γöé
- Γöé Γöé Γöé reference conversions Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Class "T" Γöé Class "T" Γöé Class "T" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Class "T" Γöé Class "X" Γöé Class type for which a Γöé
- Γöé Γöé Γöé conversion exists. If Γöé
- Γöé Γöé Γöé more than one possible Γöé
- Γöé Γöé Γöé conversion exists, the Γöé
- Γöé Γöé Γöé result is ambiguous. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé THROW expression Γöé Other (type, pointer, Γöé Type of the expression Γöé
- Γöé Γöé reference) Γöé that is not a THROW Γöé
- Γöé Γöé Γöé expression Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Examples of Conditional Expressions
-
- Related Information
-
- Type Specifiers
- Declarators
- Expressions and Operators
- Arithmetic Conversions
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Conditional Expressions ΓòÉΓòÉΓòÉ
-
- The following expression determines which variable has the greater value, y or
- z, and assigns the greater value to the variable x:
-
- x = (y > z) ? y : z;
-
- The following is an equivalent statement:
-
- if (y > z)
- x = y;
- else
- x = z;
-
- The following expression calls the function printf, which receives the value of
- the variable c, if c evaluates to a digit. Otherwise, printf receives the
- character constant 'x'.
-
- printf(" c = %c\n", isdigit(c) ? c : 'x');
-
- If the last operand of a conditional expression contains an assignment
- operator, use parentheses to ensure the expression evaluates properly. For
- example, the = operator has higher precedence than the ?: operator in the
- following expression:
-
- int i,j,k;
- (i == 7) ? j ++ : k = j;
-
- This expression generates an error because it is interpreted as if it were
- parenthesized this way:
-
- int i,j,k;
- ((i == 7) ? j ++ : k) = j;
-
- That is, k is treated as the third operand, not the entire assignment
- expression k = j. The error arises because a conditional expression is not an
- lvalue, and the assignment is not valid.
-
- To make the expression evaluate correctly, enclose the last operand in
- parentheses:
-
- int i,j,k;
- (i == 7) ? j ++ : (k = j);
-
-
- ΓòÉΓòÉΓòÉ 5.9. Assignment Expressions ΓòÉΓòÉΓòÉ
-
- An assignment expression stores a value in the object designated by the left
- operand. There are two types of assignment operators: simple assignment and
- compound assignment.
-
- The left operand in all assignment expressions must be a modifiable lvalue. The
- type of the expression is the type of the left operand. The value of the
- expression is the value of the left operand after the assignment has completed.
-
- In C, the result of an assignment expression is not an lvalue. The result of an
- assignment expression is an lvalue in C++
-
- All assignment operators have the same precedence and have right-to-left
- associativity.
-
- Simple Assignment =
- Compound Assignment
-
- Related Information
-
- Expressions and Operators
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ 5.9.1. Simple Assignment = ΓòÉΓòÉΓòÉ
-
- The simple assignment operator stores the value of the right operand in the
- object designated by the left operand.
-
- Both operands must have arithmetic types, the same structure type, or the same
- union type. Otherwise, both operands must be pointers to the same type, or the
- left operand must be a pointer and the right operand must be the constant 0 or
- NULL.
-
- If both operands have arithmetic types, the system converts the type of the
- right operand to the type of the left operand before the assignment.
-
- If the right operand is a pointer to a type, the left operand can be a pointer
- to a const of the same type. If the right operand is a pointer to a const type,
- the left operand must also be a pointer to a const type.
-
- If the right operand is a pointer to a type, the left operand can be a pointer
- to a volatile of the same type. If the right operand is a pointer to a volatile
- type, the left operand must also be a pointer to a volatile type.
-
- If the left operand is a pointer to a member, the right operand must be a
- pointer to a member or a constant expression that evaluates to zero. The right
- operand is converted to the type of the left operand before assignment.
-
- If the left operand is an object of reference type, the assignment is to the
- object denoted by the reference.
-
- If the left operand is a pointer and the right operand is the constant 0, the
- result is NULL.
-
- Pointers to void can appear on either side of the simple assignment operator.
-
- A packed structure or union can be assigned to a nonpacked structure or union
- of the same type, and a nonpacked structure or union can be assigned to a
- packed structure or union of the same type.
-
- If one operand is packed and the other is not, the layout of the right operand
- is remapped to match the layout of the left. This remapping of structures might
- degrade performance. For efficiency, when you perform assignment operations
- with structures or unions, you should ensure that both operands are either
- packed or nonpacked.
-
- Note: If you assign pointers to structures or unions, the objects they point
- to must both be either packed or nonpacked. See Pointers for more information
- on assignments with pointers.
-
- You can assign values to operands with the type qualifier volatile. You cannot
- assign a pointer of an object with the type qualifier const to a pointer of an
- object without the const type qualifier. For example:
-
- const int *p1;
- int *p2;
- p2 = p1; /* this is NOT allowed */
-
- p1 = p2; /* this IS allowed */
-
- Examples of Simple Assignments
-
- Note: The assignment (=) operator should not be confused with the equality
- comparison (==) operator. For example:
-
- if(x == 3) evaluates to 1 if x is equal to three
-
- while
- if(x = 3) is taken to be true because (x = 3) evaluates to a non-zero value
- (3). The expression also assigns the value 3 to x.
-
- Related Information
-
- Compound Assignment
- Equality == !=
- Pointers
- volatile and const Qualifiers
- Type Specifiers
- Arithmetic Conversions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Simple Assignments ΓòÉΓòÉΓòÉ
-
- The following example assigns the value of number to the member employee of the
- structure payroll:
-
- payroll.employee = number;
-
- The following example assigns in order the value 0 (zero) to strangeness, the
- value of strangeness to charm, the value of charm to beauty, and the value of
- beauty to truth:
-
- truth = beauty = charm = strangeness = 0;
-
-
- ΓòÉΓòÉΓòÉ 5.9.2. Compound Assignment ΓòÉΓòÉΓòÉ
-
- The compound assignment operators consist of a binary operator and the simple
- assignment operator. They perform the operation of the binary operator on both
- operands and give the result of that operation to the left operand.
-
- The following table shows the operand types of compound assignment expressions:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé OPERATOR Γöé LEFT OPERAND Γöé RIGHT OPERAND Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé += or -= Γöé Arithmetic Γöé Arithmetic Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé += or -= Γöé Pointer Γöé Integral type Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé *=, /=, and %= Γöé Arithmetic Γöé Arithmetic Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé <<=, >>=, &=, ^=, and Γöé Integral type Γöé Integral type Γöé
- Γöé |= Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Note that the expression a *= b + c is equivalent to a = a * (b + c), and not
- a = a * b + c.
-
- The following table lists the compound assignment operators and shows an
- expression using each operator:
-
- Operator Example
-
- += index += 2
- Equivalent expression: index = index + 2
-
- -= *(pointer++) -= 1
- Equivalent expression: *pointer = *(pointer++) - 1
-
- *= bonus *= increase
- Equivalent expression: bonus = bonus * increase
-
- /= time /= hours
- Equivalent expression: time = time / hours
-
- %= allowance %= 1000
- Equivalent expression: allowance = allowance % 1000
-
- <<= result <<= num
- Equivalent expression: result = result << num
-
- >>= form >>= 1
- Equivalent expression: form = form >> 1
-
- &= mask &= 2
- Equivalent expression: mask = mask & 2
-
- ^= test ^= pre_test
- Equivalent expression: test = test ^ pre_test
-
- |= flag |= ON
- Equivalent expression: flag = flag | ON
-
- Although the equivalent expression column shows the left operands (from the
- example column) evaluated twice, the left operand is evaluated only once.
-
- Related Information
-
- Simple Assignment =
- Binary Expressions
-
-
- ΓòÉΓòÉΓòÉ 5.10. Comma Expression , ΓòÉΓòÉΓòÉ
-
- A comma expression contains two operands separated by a comma. Although the
- compiler evaluates both operands, the value of the right operand is the value
- of the expression. The left operand is evaluated, possibly producing side
- effects, and the value is discarded. The result of a comma expression is not an
- lvalue.
-
- Both operands of a comma expression can have any type. All comma expressions
- have left-to-right associativity. The left operand is fully evaluated before
- the right operand.
-
- In the following example, if omega has the value 11, the expression increments
- delta and assigns the value 3 to alpha:
-
- alpha = (delta++, omega % 4);
-
- Any number of expressions separated by commas can form a single expression. The
- compiler evaluates the leftmost expression first. The value of the rightmost
- expression becomes the value of the entire expression.
-
- For example, the value of the expression:
-
- intensity++, shade * increment, rotate(direction);
-
- is the value of the expression:
-
- rotate(direction)
-
- The primary use of the comma operator is to produce side effects in the
- following situations:
-
- Calling a function
- Entering or repeating an iteration loop
- Testing a condition
- Other situations where a side effect is required but the result of the
- expression is not immediately needed
-
- To use the comma operator in a context where the comma has other meanings,
- such as in a list of function arguments or a list of initializers, you must
- enclose the comma operator in parentheses. For example, the function
-
- f(a, (t = 3, t + 2), c);
-
- has only three arguments: the value of a, the value 5, and the value of c. The
- value of the second argument is the result of the comma expression in
- parentheses:
-
- t = 3, t + 2
-
- which has the value 5.
-
- The following table gives some examples of the uses of the comma operator:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé STATEMENT Γöé EFFECTS Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé for (i=0; i<2; ++i, f() ); Γöé A FOR statement in which "i" is incre- Γöé
- Γöé Γöé mented and "f()" is called at each iter- Γöé
- Γöé Γöé ation. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé if ( f(), ++i, i>1 ) Γöé An IF statement in which function "f()" Γöé
- Γöé { /* ... */ } Γöé is called, variable "i" is incremented, Γöé
- Γöé Γöé and variable "i" is tested against a Γöé
- Γöé Γöé value. The first two expressions within Γöé
- Γöé Γöé this comma expression are evaluated Γöé
- Γöé Γöé before the expression "i>1". Regardless Γöé
- Γöé Γöé of the results of the first two Γöé
- Γöé Γöé expressions, the third is evaluated and Γöé
- Γöé Γöé its result determines whether the IF Γöé
- Γöé Γöé statement is processed. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé func( ( ++a, f(a) ) ); Γöé A function call to "func()" in which "a" Γöé
- Γöé Γöé is incremented, the resulting value is Γöé
- Γöé Γöé passed to a function "f()", and the Γöé
- Γöé Γöé return value of "f()" is passed to Γöé
- Γöé Γöé "func()". The function "func()" is Γöé
- Γöé Γöé passed only a single argument, because Γöé
- Γöé Γöé the comma expression is enclosed in Γöé
- Γöé Γöé parentheses within the function argument Γöé
- Γöé Γöé list. Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Related Information
-
- Expressions and Operators
- Operator Precedence and Associativity
-
-
- ΓòÉΓòÉΓòÉ 6. Implicit Type Conversions ΓòÉΓòÉΓòÉ
-
- There are two kinds of implicit type conversions: standard conversions and
- user-defined conversions. This chapter describes the following standard type
- conversions:
-
- integral promotions.
- Implicit standard type conversions:
- - Signed-integer conversions
- - Unsigned-integer conversions
- - Floating-point conversions
- - Pointer conversions
- - Reference conversions
- - Pointer-to-member conversions
- - Function argument conversions
- - Other conversions
- Arithmetic conversions.
-
- Related Information
-
- Expressions and Operators
- Functions
- Cast Expressions.
- User-Defined Conversions.
-
-
- ΓòÉΓòÉΓòÉ 6.1. Integral Promotions ΓòÉΓòÉΓòÉ
-
- Certain fundamental types can be used wherever an integer can be used. The
- fundamental types that can be converted through integral promotion are:
-
- char
- wchar_t
- short int
- enumerators
- objects of enumeration type
- integer bit fields (both signed and unsigned)
-
- Except for wchar_t, if the value cannot be represented by an int, the value is
- converted to an unsigned int. For wchar_t, if an int can represent all the
- values of the original type, the value is converted to the type that can best
- represent all the values of the original type. For example, if a long can
- represent all the values, the value is converted to a long.
-
- Note: Integral promotions are not performed on long long integers.
-
-
- ΓòÉΓòÉΓòÉ 6.2. Standard Type Conversions ΓòÉΓòÉΓòÉ
-
- Many C and C++ operators cause implicit type conversions, which change the type
- of a value. When you add values having different data types, both values are
- first converted to the same type. For example, when a short int value and an
- int value are added together, the short int value is converted to the int type.
-
- Implicit type conversions can occur when:
-
- An operand is prepared for an arithmetic or logical operation.
- An assignment is made to an lvalue that has a different type than the
- assigned value.
- A prototyped function is provided a value that has a different type than
- the parameter.
- The value specified in the return statement of a function has a different
- type from the defined return type for the function.
-
- You can perform explicit type conversions using the cast operator or the
- function style cast. For more information on explicit type conversions, see
- Cast Expressions.
-
-
- ΓòÉΓòÉΓòÉ 6.2.1. Signed-Integer Conversions ΓòÉΓòÉΓòÉ
-
- The compiler converts a signed integer to a shorter integer by truncating the
- high-order bits and converting the variable to a longer signed integer by
- sign-extension.
-
- Conversion of signed integers to floating-point values takes place without loss
- of information, except when an int or long int value is converted to a float,
- in which case some precision may be lost. When a signed integer is converted to
- an unsigned integer, the signed integer is converted to the size of the
- unsigned integer, and the result is interpreted as an unsigned value.
-
-
- ΓòÉΓòÉΓòÉ 6.2.2. Unsigned-Integer Conversions ΓòÉΓòÉΓòÉ
-
- An unsigned integer is converted to a shorter unsigned or signed integer by
- truncating the high-order bits. An unsigned integer is converted to a longer
- unsigned or signed integer by zero-extending. Zero-extending pads the leftmost
- bits of the longer integer with binary zeros.
-
- When an unsigned integer is converted to a signed integer of the same size, no
- change in the bit pattern occurs. However, the value changes if the sign bit is
- set.
-
-
- ΓòÉΓòÉΓòÉ 6.2.3. Floating-Point Conversions ΓòÉΓòÉΓòÉ
-
- A float value converted to a double undergoes no change in value. A double
- converted to a float is represented exactly, if possible. If the compiler
- cannot exactly represent the double value as a float, the value loses
- precision. If the value is too large to fit into a float, the result is
- undefined.
-
- When a floating-point value is converted to an integer value, the decimal
- fraction portion of the floating-point value is discarded in the conversion. If
- the result is too large for the given integer type, the result of the
- conversion is undefined.
-
-
- ΓòÉΓòÉΓòÉ 6.2.4. Pointer Conversions ΓòÉΓòÉΓòÉ
-
- Pointer conversions are performed when pointers are used, including pointer
- assignment, initialization, and comparison.
-
- A constant expression that evaluates to zero can be converted to a pointer.
- This pointer will be a null pointer (pointer with a zero value), and is
- guaranteed not to point to any object.
-
- Any pointer to an object that is not a const or volatile object can be
- converted to a void*. You can also convert any pointer to a function to a
- void*, provided that a void* has sufficient bits to hold it.
-
- You can convert an expression with type array of some type to a pointer to the
- initial element of the array, except when the expression is used as the operand
- of the & (address) operator or the sizeof operator.
-
- You can convert an expression with a type of function returning T to a pointer
- to a function returning T, except when the expression is used as the operand of
- the & (address) operator, the () (function call) operator, or the sizeof
- operator.
-
- You can convert an integer value to an address offset.
-
- You can convert a pointer to a class A to a pointer to an accessible base class
- B of that class, as long as the conversion is not ambiguous. The conversion is
- ambiguous if the expression for the accessible base class can refer to more
- than one distinct class. The resulting value points to the base class subobject
- of the derived class object. A null pointer (pointer with a zero value) is
- converted into itself.
-
- Note: You cannot convert a pointer to a class into a pointer to its base class
- if the base class is a virtual base class of the derived class.
-
- For more information on pointer conversions, see Pointer Arithmetic.
-
-
- ΓòÉΓòÉΓòÉ 6.2.5. Reference Conversions ΓòÉΓòÉΓòÉ
-
- A reference conversion can be performed wherever a reference initialization
- occurs, including reference initialization done in argument passing and
- function return values. A reference to a class can be converted to a reference
- to an accessible base class of that class as long as the conversion is not
- ambiguous. The result of the conversion is a reference to the base class
- subobject of the derived class object.
-
- Reference conversion is allowed if the corresponding pointer conversion is
- allowed.
-
-
- ΓòÉΓòÉΓòÉ 6.2.6. Pointer-to-Member Conversions ΓòÉΓòÉΓòÉ
-
- Pointer-to-member conversion can occur when pointers to members are
- initialized, assigned, or compared.
-
- A constant expression that evaluates to zero is converted to a distinct pointer
- to a member.
-
- Note: A pointer to a member is not the same as a pointer to an object or a
- pointer to a function.
-
- A pointer to a member of a base class can be converted to a pointer to a member
- of a derived class if the following conditions are true:
-
- The conversion is not ambiguous. The conversion is ambiguous if multiple
- instances of the base class are in the derived class.
- A pointer to the derived class can be converted to a pointer to the base
- class. If this is the case, the base class is said to be accessible. See
- Derivation Access of Base Classes for more information.
-
- For more information, see Pointers to Members and C++ Pointer to Member
- Operators .* ->*.
-
-
- ΓòÉΓòÉΓòÉ 6.2.7. Function Argument Conversions ΓòÉΓòÉΓòÉ
-
- If no function prototype declaration is visible when a function is called, the
- compiler can perform default argument promotions, which consist of the
- following:
-
- Integral promotions
- Arguments with type float are converted to type double.
-
-
- ΓòÉΓòÉΓòÉ 6.2.8. Other Conversions ΓòÉΓòÉΓòÉ
-
- By definition, the void type has no value. Therefore, it cannot be converted to
- any other type, and no other value can be converted to void by assignment.
- However, a value can be explicitly cast to void.
-
- No conversions between structure or union types are allowed.
-
- There are no standard conversions between class types.
-
- In C, when you define a value using the enum type specifier, the value is
- treated as an int. Conversions to and from an enum value proceed as for the int
- type.
-
- In C++, you can convert from an enum to any integral type but not from an
- integral type to an enum.
-
-
- ΓòÉΓòÉΓòÉ 6.3. Arithmetic Conversions ΓòÉΓòÉΓòÉ
-
- Most C++ operators perform type conversions to bring the operands of an
- expression to a common type or to extend short values to the integer size used
- by the machine. The conversions depend on the specific operator and the type of
- the operand or operands. However, many operators perform similar conversions on
- operands of integer and floating-point types. These standard conversions are
- known as the arithmetic conversions because they apply to the types of values
- ordinarily used in arithmetic.
-
- Arithmetic conversions are used for matching operands of arithmetic operators.
-
- Arithmetic conversion proceeds in the following order:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé OPERAND TYPE Γöé CONVERSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has LONG DOUBLE type Γöé The other operand is converted to Γöé
- Γöé Γöé LONG DOUBLE type. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has DOUBLE type Γöé The other operand is converted to Γöé
- Γöé Γöé DOUBLE. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has FLOAT type Γöé The other operand is converted to Γöé
- Γöé Γöé FLOAT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has UNSIGNED LONG INT Γöé The other operand is converted to Γöé
- Γöé type Γöé UNSIGNED LONG INT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has UNSIGNED LONG LONG Γöé The other operand is converted to Γöé
- Γöé INT type Γöé UNSIGNED LONG LONG INT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has UNSIGNED INT type and Γöé The operand with UNSIGNED INT type Γöé
- Γöé the other operand has LONG INT type Γöé is converted to LONG INT. Γöé
- Γöé and the value of the UNSIGNED INT can Γöé Γöé
- Γöé be represented in a LONG INT Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has UNSIGNED INT type and Γöé Both operands are converted to Γöé
- Γöé the other operand has LONG INT type Γöé UNSIGNED LONG INT Γöé
- Γöé and the value of the UNSIGNED INT Γöé Γöé
- Γöé cannot be represented in a LONG INT Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has LONG INT type Γöé The other operand is converted to Γöé
- Γöé Γöé LONG INT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has LONG LONG INT type Γöé The other operand is converted to Γöé
- Γöé Γöé LONG LONG INT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé One operand has UNSIGNED INT type Γöé The other operand is converted to Γöé
- Γöé Γöé UNSIGNED INT. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Both operands have INT type Γöé The result is type INT. Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 7. Functions ΓòÉΓòÉΓòÉ
-
- This section describes the structure and use of functions in C and C++. It
- discusses the following topics:
-
- C++ Enhancements to C Functions
- Function Declarations
- Function Definitions
- The main() Function
- Calling Functions and Passing Arguments
- Default Arguments in C++ Functions
- Inline Functions
-
- Related Information
-
- Member Functions
- Inline Member Functions
- C++ Overloading
- Special C++ Member Functions
- Virtual Functions
-
- Functions specify the logical structure of a program and define how particular
- operations are to be implemented.
-
- A function declaration consists of a return type, a name, and an argument
- list. It is used to declare the format and existence of a function prior to
- its use.
-
- A function definition contains a function declaration and the body of the
- function. A function can only have one definition.
-
- Both C++ and ANSI/ISO C use the style of declaration called prototyping. A
- prototype refers to the return type, name, and argument list components of a
- function. It is used by the compiler for argument type checking and argument
- conversions. Prototypes can appear several times in a program, provided the
- declarations are compatible. They allow the compiler to check for mismatches
- between the parameters of a function call and those in the function
- declaration.
-
- C++ Note: C++ functions must use prototypes. They are usually placed in
- header files, while function definitions appear in source files. Nonprototype
- functions are allowed in C only.
-
-
- ΓòÉΓòÉΓòÉ 7.1. C++ Enhancements to C Functions ΓòÉΓòÉΓòÉ
-
- The C++ language provides many enhancements to C functions. These are:
-
- Reference arguments
- Default arguments
- Reference return types
- Member functions
- Overloaded functions
- Operator functions
- Constructor and destructor functions
- Conversion functions
- Virtual functions
- Function templates
-
-
- ΓòÉΓòÉΓòÉ 7.2. Function Declarations ΓòÉΓòÉΓòÉ
-
- A function declaration establishes the name and the parameters of the function.
-
- Syntax of a Function Declaration
-
- A function is declared implicitly by its appearance in an expression if it has
- not been defined or declared previously; the implicit declaration is equivalent
- to a declaration of extern int func_name(). The default return type of a
- function is int.
-
- To indicate that the function does not return a value, declare it with a return
- type of void.
-
- C++ Note: The use of the const and volatile specifiers is only supported by
- C++.
-
-
- ΓòÉΓòÉΓòÉ 7.2.1. C Function Declarations ΓòÉΓòÉΓòÉ
-
- A function cannot be declared as returning a data object having a volatile or
- const type but it can return a pointer to a volatile or const object. Also, a
- function cannot return a value that has a type of array or function.
-
- If the called function returns a value that has a type other than int, you must
- declare the function before the function call. Even if a called function
- returns a type int, explicitly declaring the function prior to its call is good
- programming practice.
-
- Some declarations do not have parameter lists; the declarations simply specify
- the types of parameters and the return values, such as in the following
- example:
-
- int func(int,long);
-
- Examples of Function Declarations and Definitions
-
- Related Information
-
- Function Declarator
- Function Definitions
- Calling Functions and Passing Arguments
- extern Storage Class Specifier
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Function Declaration ΓòÉΓòÉΓòÉ
-
- A function declaration has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇfunction_declaratorΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ>
- Γö£ΓöÇexternΓöÇΓöñ ΓööΓöÇtype_specifierΓöÇΓöÿ ΓööΓöÇparameterΓöÇΓöÿ
- ΓööΓöÇstaticΓöÇΓöÿ
- >ΓöÇΓöÇ)ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- Γö£ΓöÇconstΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇvolatileΓöÇΓöÿ
-
- C++ Note: The use of the const and volatile specifiers is only supported by
- C++.
-
-
- ΓòÉΓòÉΓòÉ 7.2.2. C++ Function Declarations ΓòÉΓòÉΓòÉ
-
- In C++, you can specify the qualifiers volatile and const in member function
- declarations. You can also specify exception specifications in function
- declarations. All C++ functions must be declared before they can be called.
-
- Types cannot be defined in return or argument types. For example, the following
- declarations are not valid in C++:
-
- void print(struct X { int i; } x); //error
- enum count{one, two, three} counter(); //error
-
- This example attempts to declare a function print() that takes an object x of
- class X as its argument. However, the class definition is not allowed within
- the argument list. In the attempt to declare counter(), the enumeration type
- definition cannot appear in the return type of the function declaration. The
- two function declarations and their corresponding type definitions can be
- rewritten as follows:
-
- struct X { int i; };
- void print(X x);
- enum count {one, two, three};
- count counter();
-
- Multiple Function Declarations
-
- All function declarations for a particular function must have the same number
- and type of arguments, and must have the same return type and the same linkage
- keywords. These return and argument types are part of the function type,
- although the default arguments are not.
-
- For the purposes of argument matching, ellipsis and linkage keywords are
- considered a part of the function type. They must be used consistently in all
- declarations of a function. If the only difference between the argument types
- in two declarations is in the use of typedef names or unspecified argument
- array bounds, the declarations are the same. A const or volatile specifier is
- also part of the function type, but can only be part of a declaration or
- definition of a nonstatic member function.
-
- Declaring two functions differing only in return type is not valid function
- overloading, and is flagged as an error. For example:
-
- void f();
- int f(); // error, two definitions differ only in
- // return type
- int g()
- {
- return f();
- }
-
- Checking Function Calls
-
- The compiler checks C++ function calls by comparing the number and type of the
- actual arguments used in the function call with the number and type of the
- formal arguments in the function declaration. Implicit type conversion is
- performed when necessary.
- Argument Names in Function Declarations
-
- You can supply argument names in a function declaration, but the compiler
- ignores them except in the following two situations:
-
- 1. If two argument names have the same name within a single declaration.
- This is an error.
-
- 2. If an argument name is the same as a name outside the function. In this
- case the name outside the function is hidden and cannot be used in the
- argument declaration.
-
- In the following example, the third argument intersects is meant to have
- enumeration type subway_line, but this name is hidden by the name of the first
- argument. The declaration of the function subway() causes a compile-time error
- because subway_line is not a valid type name in the context of the argument
- declarations.
-
- enum subway_line {yonge, university, spadina, bloor};
- int subway(char * subway_line, int stations,
- subway_line intersects);
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Function Declarations and Definitions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example defines the function absolute with the return type
- double. Because this is a noninteger return type, absolute is declared prior to
- the function call.
-
- *
- ************************************************************************/
-
- /**
- ** This example shows how a function is declared and defined
- **/
-
- #include <stdio.h>
- double absolute(double);
-
- int main(void)
- {
- double f = -3.0;
-
- printf("absolute number = %lf\n", absolute(f));
-
- return (0);
- }
-
- double absolute(double number)
- {
- if (number < 0.0)
- number = -number;
-
- return (number);
- }
-
- /************************************************************************
- *
-
- Specifying a return type of void on a function declaration indicates that the
- function does not return a value. The following example defines the function
- absolute with the return type void. Within the function main, absolute is
- declared with the return type void.
-
- *
- ************************************************************************/
-
- /**
- ** This example uses a function with a void return type
- **/
-
- #include <stdio.h>
-
- int main(void)
- {
- void absolute(float);
- float f = -8.7;
-
- absolute(f);
-
- return(0);
- }
-
- void absolute(float number)
- {
- if (number < 0.0)
- number = -number;
-
- printf("absolute number = %f\n", number);
- }
-
- The following code fragments show several function declarations. The first
- declares a function f that takes two integer arguments and has a return type of
- void:
-
- void f(int, int);
-
- The following code fragment declares a function f1 that takes an integer
- argument, and returns a pointer to a function that takes an integer argument
- and returns an integer:
-
- int (*f1(int))(int);
-
- Alternatively, a typedef can be used for the complicated return type of
- function f1:
-
- typedef int pf1(int);
- pf1* f1(int);
-
- The following code fragment declares a pointer p1 to a function that takes a
- pointer to a constant character and returns an integer:
-
- int (*p1) (const char*);
-
- The following declaration is of an external function f2 that takes a constant
- integer as its first argument, can have a variable number and variable types of
- other arguments, and returns type int.
-
- int extern f2(const int ...);
-
- Function f3 takes an int argument with a default value that is the value
- returned from function f2, and that has a return type of int:
-
- const int j = 5;
- int f3( int x = f2(j) );
-
- Function f6 is a constant class member function of class X with no arguments,
- and with an int return type:
-
- class X
- {
- public:
- int f6() const;
- };
-
- Function f4 takes no arguments, has return type void, and can throw class
- objects of types X and Y.
-
- class X;
- class Y;
- // .
- // .
- // .
- void f4() throw(X,Y);
-
- Function f5 takes no arguments, has return type void, and cannot throw an
- exception.
-
- void f5() throw();
-
-
- ΓòÉΓòÉΓòÉ 7.3. Function Definitions ΓòÉΓòÉΓòÉ
-
- A function definition contains a function declaration and the body of a
- function. It specifies the function name, formal parameters, the return type,
- and storage class of the function.
-
- Syntax of a Function Definition
-
- A function definition (either prototype or nonprototype) contains the
- following:
-
- An optional storage class specifier extern or static, which determines
- the scope of the function. If a storage class specifier is not given, the
- function has external linkage.
- An optional linkage keyword, which determines the calling convention used
- to call the function. The keywords are a VisualAge for C++ extension to
- the ANSI/ISO C definition. The default VisualAge for C++ calling
- convention is _Optlink. The _Optlink calling convention is described in
- the IBM VisualAge for C++ for Windows User's Guide.
- An optional type specifier, which determines the type of value that the
- function returns. If a type specifier is not given, the function has type
- int.
- A function declarator, which provides the function with a name, can
- further describe the type of the value that the function returns, and can
- list any parameters that the function expects and their types. The
- parameters that the function is expecting are enclosed in parentheses.
- A block statement, which contains data definitions and code.
-
- A nonprototype function definition can also have a list of parameter
- declarations, which describe the types of parameters that the function
- receives. In nonprototype functions, parameters that are not declared have
- type int.
-
- A function can be called by itself or by other functions. Unless a function
- definition has the storage class specifier static, the function also can be
- called by functions that appear in other files. Functions with a storage class
- specifier of static can only be directly invoked from within the same source
- file.
-
- If a function has the storage class specifier static or a return type other
- than int, the function definition or a declaration for the function must
- appear before, and in the same file as, a call to the function.
-
- In C only, if a function definition has external linkage and a return type of
- int, calls to the function can be made before it is visible because an
- implicit declaration of extern int func(); is assumed. This is not true for
- C++.
-
- All declarations for a given function must be compatible; that is, the return
- type is the same and the parameters have the same type.
-
- The default type for the return value and parameters of a function is int, and
- the default storage class specifier is extern. If the function does not return
- a value or it is not passed any parameters, use the keyword void as the type
- specifier.
-
- A function can return a pointer or reference to a function, array, or to an
- object with a volatile or const type. In C, you cannot declare a function as a
- struct or union member. (This restriction does not apply to C++.)
-
- A function cannot have a return type of function or array. In C, a function
- cannot return any type having the volatile or const qualifier. (This
- restriction does not apply to C++.)
-
- You cannot define an array of functions. You can, however, define an array of
- pointers to functions.
-
- Examples of Function Definitions
-
- Related Information
-
- Storage Class Specifiers
- Linkage Keywords
- Type Specifiers
- Function Declarator
- Block
- volatile and const Qualifiers
- Function Declarations
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Function Definition ΓòÉΓòÉΓòÉ
-
- A function definition has the form:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ>
- Γö£ΓöÇexternΓöÇΓöñ ΓööΓöÇlinkage_specifierΓöÇΓöÿ ΓööΓöÇtype_specifierΓöÇΓöÿ
- ΓööΓöÇstaticΓöÇΓöÿ
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >ΓöÇΓöÇfunction_declaratorΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇblock_statementΓöÇΓöÇ><
- ΓööΓöÇparameter_declarationΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Function Definitions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, ary is an array of two function pointers. Type
- casting is performed to the values assigned to ary for compatibility:
-
- *
- ************************************************************************/
-
- /**
- ** This example uses an array of pointers to functions
- **/
-
- #include <stdio.h>
-
- int func1(void);
- void func2(double a);
-
- int main(void)
- {
- double num;
- int retnum;
- void (*ary[2]) ();
- ary[0] = ((void(*)())func1);
- ary[1] = ((void(*)())func2);
-
- retnum=((int (*)())ary[0])(); /* calls func1 */
- printf("number returned = %i\n", retnum);
- ((void (*)(double))ary[1])(num); /* calls func2 */
-
- return(0);
- }
-
- int func1(void)
- {
- int number=3;
- return number;
- }
-
- void func2(double a)
- {
- a=333.3333;
- printf("result of func2 = %f\n", a);
- }
-
- /************************************************************************
- *
-
- The following example is a complete definition of the function sum:
-
- int sum(int x,int y)
- {
- return(x + y);
- }
-
- The function sum has external linkage, returns an object that has type int, and
- has two parameters of type int declared as x and y. The function body contains
- a single statement that returns the sum of x and y.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 7.3.1. Linkage Keywords ΓòÉΓòÉΓòÉ
-
- Use linkage keywords to set calling conventions for function calls. Each
- calling convention has a corresponding keyword that you can use with a function
- name to set the convention for that function.
-
- Using linkage keywords with data generates an error.
-
- Note: Using a linkage keyword is generally quicker and easier than using a
- #pragma linkage and they let you declare both the function and its
- linkage type in one statement. Because the #pragma linkage directive is
- obsolete in VisualAge for C++, linkage keywords are the preferred method
- for setting the calling conventions. Do not use #pragma linkage in new
- code. For your new applications, use linkage keywords to specify the
- calling convention for a function.
-
- C++ Note: #pragma linkage is not supported at all for C++ functions.
-
- The linkage keywords for calling conventions are:
-
- _Optlink
- _System
- __stdcall
- __cdecl
-
- You can use these linkage keywords at any language level. The VisualAge for
- C++ default linkage is _Optlink.
-
- The default linkage convention for C++ member functions is _Optlink. Other
- linkage conventions are permitted to allow a parameters to be passed in a
- different order from _Optlink.
-
- A member function with linkage other than _Optlink still has a this pointer.
- The signature of a member function with linkage other than _Optlink is
- unchanged. The _System calling convention is equivalent to __stdcall linkage
- because __stdcall is the linkage used by the system APIs. It is still treated
- as a distinct linkage convention, however.
-
- The keywords used in the following function calling conventions are reserved
- by the compiler, but the calling conventions themselves are not supported by
- IBM VisualAge for C++ for Windows
-
- _Pascal
- _Far32 _Pascal
- _Far16 _Cdecl
- _Far16 _Pascal
- _Far16 _Fastcall
- Using the keywords as calling conventions causes a warning to be issued, and
- the default linkage, _Optlink, is used.
-
- The VisualAge for C++ compiler provides the following linkage keywords in ansi
- and extended modes for compatibility with Microsoft Visual C++:
-
- __optlink
- __system
-
- The VisualAge for C++ compiler provides the following linkage keywords in
- extended mode for compatibility with Microsoft Visual C++:
-
- _cdecl
- _stdcall
-
- To set the calling convention for a function, place the linkage keyword
- immediately before the function name or at the beginning of the declarator.
- For example:
-
- int _Optlink deborah(int);
- char (__stdcall * albert)(void);
-
- At link time, function names are decorated according to the linkage convention
- specified. The following decorations are used:
-
- Linkage Convention Name Decoration
-
- _Optlink Function names are decorated with a question mark prefix (?) when
- they appear in object modules. For example, a function named fred
- in the source program will appear as ?fred in the object.
-
- __stdcall and _System Function names are decorated with an underscore prefix
- (_), and a suffix which consists of an at sign (@), followed by
- the number of bytes of parameters (in decimal). Parameters of less
- than four bytes are rounded up to four bytes. Structure sizes are
- also rounded up to a multiple of four bytes. For example, a
- function fred prototyped as follows:
-
- int fred(int, int, short);
-
- would appear as:
-
- _fred@12
-
- in the object module.
-
- __cdecl Function names are decorated with an underscore prefix (_) when
- they appear in object modules. For example, a function named fred
- in the source program will appear as _fred in the object.
-
- Linkage keywords take precedence over the compiler options that set calling
- conventions (/Mc, /Mp, /Ms, and /Mt). Specifying conflicting linkage types for
- a function generates an error.
-
- When the /Wgen is used, a warning is issued if a declaration contains the same
- keyword more than once.
-
- For more information about using calling conventions and their keywords, see
- the IBM VisualAge for C++ for Windows Programming Guide.
-
- Related Information
-
- #pragma linkage
- /Mp and /Ms options
- Function Declarations
- Function Definitions
-
-
- ΓòÉΓòÉΓòÉ 7.3.2. Function Declarator ΓòÉΓòÉΓòÉ
-
- The function declarator names the function and lists the function parameters.
- It contains an identifier that names the function and a list of the function
- parameters. You should always use prototype function declarators because of the
- parameter checking that can be performed. C++ functions must have prototype
- function declarators.
- Prototype Function Declarators
-
- Each parameter should be declared within the function declarator. Any calls to
- the function must pass the same number of arguments as there are parameters in
- the declaration.
- Nonprototype Function Declarators
-
- Each parameter should be declared in a parameter declaration list following the
- declarator. If a parameter is not declared, it has type int.
-
- char and short parameters are widened to int, and float to double. No type
- checking between the argument type and the parameter type is done for
- nonprototyped functions. As well, there are no checks to ensure that the number
- of arguments matches the number of parameters.
-
- Each value that a function receives should be declared in a parameter
- declaration list for nonprototype function definitions that follows the
- declarator.
-
- A parameter declaration determines the storage class specifier and the data
- type of the value.
-
- The only storage class specifier allowed is the register storage class
- specifier. Any type specifier for a parameter is allowed. If you do not specify
- the register storage class specifier, the parameter will have the auto storage
- class specifier. If you omit the type specifier and you are not using the
- prototype form to define the function, the parameter will have type int.
-
- int func(i,j)
- {
- /* i and j have type int */
- }
-
- You cannot declare a parameter in the parameter declaration list if it is not
- listed within the declarator.
-
- Related Information
-
- Function Declarations
- Function Definitions
- Function Body
- Functions
- Declarations
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Function Declarator ΓòÉΓòÉΓòÉ
-
- A function declarator has the form:
-
- >>ΓöÇΓöÇdeclaratorΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇparameter_declaration_listΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇidentifierΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- A parameter declaration list has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé
- >>ΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇstorage_class_specifierΓöÇΓö¼Γö┤ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓö┤ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- Γö£ΓöÇtype_specifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇdeclaratorΓöÇΓöÇΓöÇΓöñ ΓööΓöÇ,ΓöÇΓöÇ...ΓöÇΓöÿ
- ΓööΓöÇtype_qualifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ Γöé ΓööΓöÇ*ΓöÇΓöÿ Γöé
- ΓööΓöÇabstract_declaratorΓöÇΓöÿ
-
- An abstract declarator has the form:
-
- ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇΓö¼ΓöÇ(ΓöÇΓöÇabstract_declaratorΓöÇΓöÇ)ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ*ΓöÇΓöÿ ΓööΓöÇΓöñ direct_abstract_declarator Γö£ΓöÇΓöÿ
- DIRECT_ABSTRACT_DECLARATOR:
- Γö£ΓöÇΓöÇabstract_declaratorΓöÇΓöÇΓö¼ΓöÇ[ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ]ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöñ
- Γöé ΓööΓöÇconstant_expressionΓöÇΓöÿ Γöé
- ΓööΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÿ
- ΓööΓöÇparameter_declaration_listΓöÇΓöÿ
- ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇ
-
-
- ΓòÉΓòÉΓòÉ 7.3.3. Ellipsis and void ΓòÉΓòÉΓòÉ
-
- An ellipsis at the end of a parameter declaration indicates that the number of
- arguments is equal to, or greater than, the number of specified argument types.
- At least one parameter declaration must come before the ellipsis. Where it is
- permitted, an ellipsis preceded by a comma is equivalent to a simple ellipsis.
-
- int f(int,...);
-
- The comma before the ellipsis is optional in C++ only
-
- Parameter promotions are performed as needed, but no type checking is done on
- the variable arguments.
-
- You can declare a function with no arguments in two ways:
-
- int f(void); // ANSI/ISO C Standard
-
- int f(); // C++ enhancement
- // Note: In ANSI/ISO C, this declaration means that
- // f may take any number or type or parameters
-
- An empty argument declaration list or the argument declaration list of (void)
- indicates a function that takes no arguments. void cannot be used as an
- argument type, although types derived from void (such as pointers to void) can
- be used.
-
- In the following example, the function f() takes one integer parameter and
- returns no value, while g() expects no parameters and returns an integer.
-
- void f(int);
- int g(void);
-
-
- ΓòÉΓòÉΓòÉ 7.3.4. Function Body ΓòÉΓòÉΓòÉ
-
- The body of a function is a block statement.
-
- The following function body contains a definition for the integer variable
- big_num, an if-else control statement, and a call to the function printf:
-
- void largest(int num1, int num2)
- {
- int big_num;
-
- if (num1 >= num2)
- big_num = num1;
- else
- big_num = num2;
-
- printf("big_num = %d\n", big_num);
- }
-
- Examples of Prototype Function Declarators
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Prototype Function Declarators ΓòÉΓòÉΓòÉ
-
- The following example contains a function declarator sort with table declared
- as a pointer to int and length declared as type int. Note that arrays as
- parameters are implicitly converted to a pointer to the type.
-
- /**
- ** This example illustrates function declarators.
- ** Note that arrays as parameters are implicitly
- ** converted to a pointer to the type.
- **/
-
- #include <stdio.h>
-
- void sort(int table[ ], int length);
-
- int main(void)
- {
- int table[ ]={1,5,8,4};
- int length=4;
- printf("length is %d\n",length);
- sort(table,length);
- }
-
- void sort(int table[ ], int length)
- {
- int i, j, temp;
-
- for (i = 0; i < length -1; i++)
- for (j = i + 1; j < length; j++)
- if (table[i] > table[j])
- {
- temp = table[i];
- table[i] = table[j];
- table[j] = temp;
- }
- }
-
- The following examples contain prototype function declarators:
-
- double square(float x);
- int area(int x,int y);
- static char *search(char);
-
- The following example illustrates how a typedef identifier can be used in a
- function declarator:
-
- typedef struct tm_fmt { int minutes;
- int hours;
- char am_pm;
- } struct_t;
- long time_seconds(struct_t arrival)
-
- The following function set_date declares a pointer to a structure of type date
- as a parameter. date_ptr has the storage class specifier register.
-
- set_date(register struct date *date_ptr)
- {
- date_ptr->mon = 12;
- date_ptr->day = 25;
- date_ptr->year = 87;
- }
-
- Related Information
-
- Block
- Function Definitions
- Function Declarations
-
-
- ΓòÉΓòÉΓòÉ 7.4. The main() Function ΓòÉΓòÉΓòÉ
-
- When a program begins running, the system automatically calls the function
- main, which marks the entry point of the program. Every program must have one
- function named main. No other function in the program can be called main.
-
- Syntax of the main Function
-
- By default, main has the storage class extern and a return type of int. It can
- also be declared to return void.
-
- In C++, you cannot declare main as inline or static. You cannot call main from
- within a program or take the address of main.
-
-
- ΓòÉΓòÉΓòÉ 7.4.1. Arguments to main ΓòÉΓòÉΓòÉ
-
- Syntax of the Arguments to main
-
- The function main can be declared with or without arguments that pass program
- parameters and environment settings to the program. Although any name can be
- given to these parameters, they are usually referred to as argc, argv, and
- envp.
-
- argc Is the argument count. It has type int and indicates how many
- arguments are entered on the command line.
-
- argv Is the argument vector. It is an array of pointers to char
- array objects. These char objects are null-terminated strings
- that are the program arguments passed to the program when it
- is invoked.
-
- envp Is an optional environment pointer. It is an array of pointers
- to char objects that are the environment variables available
- to the program. These have the form name=value. The system
- determines the value of this parameter during program
- initialization (before calling main). Because you can use the
- function getenv to get the value of these pointers, there is
- usually no need to declare this parameter.
-
- The value of argc indicates the number of pointers in the array argv. If a
- program name is available, the first element in argv points to a character
- array that contains the program name or the invocation name of the program
- that is being run. If the name cannot be determined, the first element in argv
- points to a null character.
-
- This name is counted as one of the arguments to the function main. For
- example, if only the program name is entered on the command line, argc has a
- value of 1 and argv[0] points to the program name.
-
- Regardless of the number of arguments entered on the command line, argv[argc]
- always contains NULL.
-
- Example of Arguments to main
-
- Related Information
-
- Function Definitions
- Calling Functions and Passing Arguments
- Type Specifiers
- Identifiers
- Block
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of the main Function ΓòÉΓòÉΓòÉ
-
- The main function has the form:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇmainΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇblock_statementΓöÇΓöÇ><
- Γö£ΓöÇvoidΓöÇΓöñ Γö£ΓöÇvoidΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇintΓöÇΓöÇΓöÿ ΓööΓöÇparametersΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of the Arguments to main ΓòÉΓòÉΓòÉ
-
- The main function has the following arguments:
-
- >>ΓöÇΓöÇintΓöÇΓöÇargcΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ, char*ΓöÇΓöÇargvΓöÇΓöÇ[]ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ
- ΓööΓöÇ, char*ΓöÇΓöÇenvpΓöÇΓöÇ[]ΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Arguments to main ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program backward prints the arguments entered on a command line
- such that the last argument is printed first:
-
- *
- ************************************************************************/
-
- #include <stdio.h>
- int main(int argc, char *argv[])
- {
- while (--argc > 0)
- printf("%s ", argv[argc]);
- }
-
- /************************************************************************
- *
-
- Invoking this program from a command line with the following:
-
- backward string1 string2
-
- gives the following output:
-
- string2 string1
-
- The arguments argc and argv would contain the following values:
-
- Object Value
- argc 3
- argv[0] pointer to string "backward"
- argv[1] pointer to string "string1"
- argv[2] pointer to string "string2"
- argv[3] NULL
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 7.5. Calling Functions and Passing Arguments ΓòÉΓòÉΓòÉ
-
- A function call specifies a function name and a list of arguments. The calling
- function passes the value of each argument to the specified function. The
- argument list is surrounded by parentheses, and each argument is separated by a
- comma. The argument list can be empty. When a function is called, the actual
- arguments are used to initialize the formal arguments.
-
- The type of an actual argument is checked against the type of the corresponding
- formal argument in the function prototype. All standard and user-defined type
- conversions are applied as necessary.
-
- For example:
-
- #include <iostream.h>
- #include <math.h>
- extern double root(double, double); // declaration
- double root(double value, double base) // definition
- {
- double temp = exp(log(value)/base);
- return temp;
- }
- void main()
- {
- int value = 144;
- int base = 2;
- // Call function root and print return value
- cout << "The root is: " << root(value,base) << endl;
- }
-
- The output is The root is: 12
-
- In the above example, because the function root is expecting arguments of type
- double, the two int arguments value and base are implicitly converted to type
- double when the function is called.
-
- The arguments to a function are evaluated before the function is called. When
- an argument is passed in a function call, the function receives a copy of the
- argument value. If the value of the argument is an address, the called function
- can use indirection to change the contents pointed to by the address. If a
- function or array is passed as an argument, the argument is converted to a
- pointer that points to the function or array.
-
- Arguments passed to parameters in prototype declarations will be converted to
- the declared parameter type. For nonprototype function declarations, char and
- short parameters are promoted to int, and float to double.
-
- You can pass a packed structure argument to a function expecting a nonpacked
- structure of the same type and vice versa. (The same applies to packed and
- nonpacked unions.)
-
- Note: If you do not use a function prototype and you send a packed structure
- when a nonpacked structure is expected, a runtime error may occur.
-
- The order in which arguments are evaluated and passed to the function is
- implementation-defined. For example, the following sequence of statements calls
- the function tester:
-
- int x;
- x = 1;
- tester(x++, x);
-
- The call to tester in the example may produce different results on different
- compilers. Depending on the implementation, x++ may be evaluated first or x may
- be evaluated first. To avoid the ambiguity and have x++ evaluated first,
- replace the preceding sequence of statements with the following:
-
- int x, y;
- x = 1;
- y = x++;
- tester(y, x);
-
-
- ΓòÉΓòÉΓòÉ 7.5.1. Passing Arguments in C++ ΓòÉΓòÉΓòÉ
-
- In C++, if a nonstatic class member function is passed as an argument, the
- argument is converted to a pointer to member.
-
- If a class has a destructor or a copy constructor that does more than a bitwise
- copy, passing a class object by value results in the construction of a
- temporary that is actually passed by reference.
-
- It is an error when a function argument is a class object and all of the
- following properties hold:
-
- The class needs a copy constructor.
- The class does not have a user-defined copy constructor.
- A copy constructor cannot be generated for that class.
-
- Examples of Calling Functions and Passing Arguments
-
- Related Information
-
- Passing Arguments by Reference
- Constructors and Destructors Overview
- Member Functions
- Function Declarator
- Function Declarations
- Function Definitions
- Type Specifiers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Calling Functions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following statement calls the function startup and passes no parameters:
-
- startup();
-
- The following function call causes copies of a and b to be stored in a local
- area for the function sum. The function sum runs using the copies of a and b.
-
- sum(a, b);
-
- The following function call passes the value 2 and the value of the expression
- a +b to sum:
-
- sum(2, a + b);
-
- The following statement calls the function printf, which receives a character
- string and the return value of the function sum, which receives the values of a
- and b:
-
- printf("sum = %d\n", sum(a,b));
-
- The following program passes the value of count to the function increment.
- increment increases the value of the parameter x by 1.
-
- *
- ************************************************************************/
-
- /**
- ** This example shows how a parameter is passed to a function
- **/
-
- #include <stdio.h>
-
- void increment(int);
-
- int main(void)
- {
- int count = 5;
-
- /* value of count is passed to the function */
- increment(count);
- printf("count = %d\n", count);
-
- return(0);
- }
-
- void increment(int x)
- {
- ++x;
- printf("x = %d\n", x);
- }
-
- /************************************************************************
- *
-
- The output illustrates that the value of count in main remains unchanged:
-
- x = 6
- count = 5
-
- In the following program, main passes the address of count to increment. The
- function increment was changed to handle the pointer. The parameter x is
- declared as a pointer. The contents to which x points are then incremented.
-
- *
- ************************************************************************/
-
- /**
- ** This example shows how an address is passed to a function
- **/
-
- #include <stdio.h>
-
- int main(void)
- {
- void increment(int *x);
- int count = 5;
-
- /* address of count is passed to the function */
- increment(&count);
- printf("count = %d\n", count);
-
- return(0);
- }
-
- void increment(int *x)
- {
- ++*x;
- printf("*x = %d\n", *x);
- }
-
- /************************************************************************
- *
-
- The output shows that the variable count is increased:
-
- *x = 6
- count = 6
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 7.5.2. Passing Arguments by Reference ΓòÉΓòÉΓòÉ
-
- If you use a reference type as a formal argument, you can make a
- pass-by-reference call to a function. In a pass-by-reference call, the values
- of arguments in the calling function can be modified in the called function. In
- pass-by-value calls, only copies of the arguments are passed to the function.
-
- Note: The term pass by reference describes a general method of passing
- arguments from a calling routine to a called routine.
-
- C++ Note: The term reference in the context of C++ refers to a specific way of
- declaring objects and functions.
-
- Example of Passing Arguments by Reference
-
- Ellipsis arguments cannot be passed as references.
-
- In addition, when the actual argument cannot be referenced directly by the
- formal argument, the compiler creates a temporary variable that is referenced
- by the formal argument and initialized using the value of the actual argument.
- In this case, the formal argument must be a const reference.
-
- Reference arguments declared const can be used to pass large objects
- efficiently to functions without making a temporary copy of the object that is
- passed to the function. Because the reference is declared const, the actual
- arguments cannot be changed by the function. For example:
-
- void printbig (const bigvar&); // Function prototype
-
- When a function printbig is called, it cannot modify the object of type bigvar
- because the object was passed by constant reference.
-
- Related Information
-
- Calling Functions and Passing Arguments
- References
- volatile and const Qualifiers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Passing Arguments by Reference ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows how arguments are passed by reference. Note that
- reference formal arguments are initialized with the actual arguments when the
- function is called.
-
- *
- ************************************************************************/
-
- /**
- ** This example shows how arguments are passed by reference
- **/
-
- #include <iostream.h>
- void swapnum(int &i, int &j)
- {
- int temp = i;
- i = j;
- j = temp;
- }
- // .
- // .
- // .
- main()
- {
- int a = 10, // a is 10
- b = 20; // b is 20
- swapnum(a,b); // now a is 20 and b is 10
- cout << "A is : " << a
- << " and B is : " << b << endl;
- }
-
- /************************************************************************
- *
-
- When the function swapnum() is called, the actual values of the variables a and
- b are exchanged because they are passed by reference. The output is:
-
- A is : 20 and B is : 10
-
- You must define the formal arguments of swapnum() as references if you want the
- values of the actual arguments to be modified by the function swapnum().
-
- *
- ************************************************************************/
-
- If the last argument specified in the function declaration before the ellipsis
- is a reference argument, arguments passed using an ellipsis (variable
- arguments) are accessible using the mechanism from the <stdarg.h> standard
- header file.
-
-
- ΓòÉΓòÉΓòÉ 7.6. Default Arguments in C++ Functions ΓòÉΓòÉΓòÉ
-
- In C++, you can provide default values for function arguments. All default
- argument names of a function are bound when the function is declared. All
- functions have their types checked at declaration, and are evaluated at each
- point of call.
-
- For example:
-
- /**
- ** This example illustrates default function arguments
- **/
-
- #include <iostream.h>
- int a = 1;
- int f(int a) {return a;}
- int g(int x = f(a)) {return f(a);}
-
- int h()
- {
- a=2;
- {
- int a = 3;
- return g();
- }
- }
-
- main()
- {
- cout << h() << endl;
- }
-
- This example prints 2 to standard output, because the a referred to in the
- declaration of g() is the one at file scope, which has the value 2 when g() is
- called. The value of a is determined after entry into function h() but before
- the call to g() is resolved.
-
- A default argument can have any type.
-
- A pointer to a function must have the same type as the function. Attempts to
- take the address of a function by reference without specifying the type of the
- function produce an error. The type of a function is not affected by arguments
- with default values.
-
- The following example shows that a function with default arguments does not
- change its type. The default argument allows you to call a function without
- specifying all of the arguments, it does not allow you to create a pointer to
- the function that does not specify the types of all the arguments. Function f
- can be called without an explicit argument, but the pointer badpointer cannot
- be defined without specifying the type of the argument:
-
- int f(int = 0);
- void g()
- {
- int a = f(1); // ok
- int b = f(); // ok, default argument used
- }
- int (*pointer)(int) = &f; // ok, type of f() specified (int)
- int (*badpointer)() = &f; // error, badpointer and f have
- // different types. badpointer must
- // be initialized with a pointer to
- // a function taking no arguments.
-
- For additional information about default arguments, see:
-
- Restrictions on Default Arguments
- Evaluating Default Arguments
-
- Related Information
-
- Calling Functions and Passing Arguments
- Functions
-
-
- ΓòÉΓòÉΓòÉ 7.6.1. Restrictions on Default Arguments ΓòÉΓòÉΓòÉ
-
- Of the operators, only the function call operator and the operator new can have
- default arguments when they are overloaded.
-
- Arguments with default values must be the trailing arguments in the function
- declaration argument list. For example:
-
- void f(int a, int b = 2, int c = 3); // trailing defaults
- void g(int a = 1, int b = 2, int c); // error, leading defaults
- void h(int a, int b = 3, int c); // error, default in middle
-
- Once a default argument has been given in a declaration or definition, you
- cannot redefine that argument, even to the same value. However, you can add
- default arguments not given in previous declarations. For example, the last
- declaration below attempts to redefine the default values for a and b:
-
- void f(int a, int b, int c=1); // valid
- void f(int a, int b=1, int c); // valid, add another default
- void f(int a=1, int b, int c); // valid, add another default
- void f(int a=1, int b=1, int c=1); // error, redefined defaults
-
- You can supply any default argument values in the function declaration or in
- the definition. All subsequent arguments must have default arguments supplied
- in this or a previous declaration of the function.
-
- You cannot use local variables in default argument expressions. For example,
- the compiler generates errors for both function g() and function h() below:
-
- void f(int a)
- {
- int b=4;
- void g(int c=a); // Local variable "a" inaccessible
- void h(int d=b); // Local variable "b" inaccessible
- }
-
- Related Information
-
- Function Calls ( )
- C++ new Operator
- Default Arguments in C++ Functions
- Evaluating Default Arguments
- Calling Functions and Passing Arguments
- Functions
-
-
- ΓòÉΓòÉΓòÉ 7.6.2. Evaluating Default Arguments ΓòÉΓòÉΓòÉ
-
- When a function defined with default arguments is called with trailing
- arguments missing, the default expressions are evaluated. For example:
-
- void f(int a, int b = 2, int c = 3); // declaration
- // ...
- int a = 1;
- f(a); // same as call f(a,2,3)
- f(a,10); // same as call f(a,10,3)
- f(a,10,20); // no default arguments
-
- Default arguments are checked against the function declaration and evaluated
- when the function is called. The order of evaluation of default arguments is
- undefined. Default argument expressions cannot use formal arguments of a
- function. For example:
-
- int f(int q = 3, int r = q); // error
-
- The argument r cannot be initialized with the value of the argument q because
- the value of q may not be known when it is assigned to r. If the above function
- declaration is rewritten:
-
- int q=5;
- int f(int q = 3, int r = q); // error
-
- the value of r in the function declaration still produces an error because the
- variable q defined outside of the function is hidden by the argument q declared
- for the function. Similarly:
-
- typedef double D;
- int f(int D, int z = D(5.3) ); // error
-
- Here the type D is interpreted within the function declaration as the name of
- an integer. The type D is hidden by the argument D. The cast D(5.3) is
- therefore not interpreted as a cast because D is the name of the argument not a
- type.
-
- In the following example, the nonstatic member a cannot be used as an
- initializer because a does not exist until an object of class X is constructed.
- You can use the static member b as an initializer because b is created
- independently of any objects of class X. You can declare the member b after its
- use as a default argument because the default values are not analyzed until
- after the final bracket } of the class declaration.
-
- class X
- {
- int a;
- f(int z = a) ; // error
- g(int z = b) ; // valid
- static int b;
- };
-
- You must put parentheses around default argument expressions that contain
- template references. In the following example:
-
- class C {
- void f(int i = X<int,5>::y);
- };
-
- the compiler cannot tell that the < represents the start of a template argument
- list and not the less than operator because the default argument X<int,5>::y
- cannot be processed until the end of the class.
-
- To avoid error messages, put parentheses around the expression containing the
- default argumement:
-
- class C {
- void f( int i = (X<int,5>::y) );
- };
-
- Related Information
-
- Default Arguments in C++ Functions
- Restrictions on Default Arguments
- Calling Functions and Passing Arguments
- Functions
- Constructors and Destructors Overview
-
-
- ΓòÉΓòÉΓòÉ 7.7. Function Return Values ΓòÉΓòÉΓòÉ
-
- A value must be returned from a function unless the function has a return type
- of void. The return value is specified in a return statement. The following
- code fragment shows a function definition, including the return statement:
-
- int add(int i, int j)
- {
- return i + j; // return statement
- }
-
- The function add() can be called as shown in the following code fragment:
-
- int a = 10,
- b = 20;
- int answer = add(a, b); // answer is 30
-
- In this example, the return statement initializes a variable of the returned
- type. The variable answer is initialized with the int value 30. The type of the
- returned expression is checked against the returned type. All standard and
- user-defined conversions are performed as necessary.
-
- The following return statements show different ways of returning values to a
- caller:
-
- return; // Returns no value
- return result; // Returns the value of result
- return 1; // Returns the value 1
- return (x * x); // Returns the value of x * x
-
- Other than main(), if a function that does not have type void returns without a
- value (as in the first return statement shown in the example above) the result
- returned is undefined. In C++, the compiler issues an error message as well.
-
- If main has a return type of int, and does not contain a return expression, it
- returns the value zero.
-
- Each time a function is called, new copies of its local variables are created.
- Because the storage for a local variable may be reused after the function has
- terminated, a pointer to a local variable or a reference to a local variable
- should not be returned.
-
- If a class object is returned, a temporary object may be created if the class
- has copy constructors or a destructor.
-
- References can also be used as return types for functions. The reference
- returns the lvalue of the object to which it refers. This allows you to place
- function calls on the left side of assignment statements. Referenced return
- values are used when assignment operators and subscripting operators are
- overloaded so that the results of the overloaded operators can be used as
- actual values.
-
- Note: Returning a reference to an automatic variable gives unpredictable
- results.
-
- Related Information
-
- return
- Calling Functions and Passing Arguments
- The main() Function
- Temporary Objects
- Special Overloaded Operators
-
-
- ΓòÉΓòÉΓòÉ 7.8. Pointers to Functions ΓòÉΓòÉΓòÉ
-
- A pointer to a function points to the address of the function's executable
- code. You can use pointers to call functions and to pass functions as arguments
- to other functions. You cannot perform pointer arithmetic on pointers to
- functions.
-
- The type of a pointer to a function is based on both the return type and
- argument types of the function.
-
- A declaration of a pointer to a function must have the pointer name in
- parentheses. Without them, the compiler interprets the statement as a function
- that returns a pointer to a specified return type. For example:
-
- int *f(int a); // function f returning an int*
- int (*g)(int a); // pointer g to a function returning an int
-
- In the first declaration, f is interpreted as a function that takes an int as
- argument, and returns a pointer to an int. In the second declaration, g is
- interpreted as a pointer to a function that takes an int argument and that
- returns an int.
-
- For more information on pointers, see Pointers and Pointer Conversions.
-
-
- ΓòÉΓòÉΓòÉ 7.9. Inline Functions ΓòÉΓòÉΓòÉ
-
- Inline functions are used to reduce the overhead of a normal function call. A
- function is declared inline by using the specifiers described below. The inline
- specifiers are a suggestion to the compiler that an inline expansion can be
- performed. Instead of transferring control to and from the function code
- segment, a modified copy of the function body may be substituted directly for
- the function call.
-
- An inline function can be declared and defined simultaneously. If it is
- declared with one of the inline specifier keywords, it can be declared without
- a definition. The following code fragment shows an inline function definition.
- Note that the definition includes both the declaration and body of the inline
- function.
-
- inline int add(int i, int j) { return i + j; }
-
- Both member and nonmember functions can be inline, and both have internal
- linkage.
-
- The use of the inline specifier does not change the meaning of the function.
- The inline expansion of a function may not preserve the order of evaluation of
- the actual arguments.
-
- For more information on inlining, see the IBM VisualAge for C++ for Windows
- Programming Guide.
-
- Related Information
-
- Inline Specifiers
- Inline Member Functions
- Functions
-
-
- ΓòÉΓòÉΓòÉ 7.9.1. Inline Specifiers ΓòÉΓòÉΓòÉ
-
- VisualAge for C++ provides keywords that you can use to specify functions that
- you want the compiler to inline:
-
- _Inline, _inline, and __inline for C programs
- inline for C++ programs
- For example:
-
- _Inline int catherine(int a);
-
- causes catherine to be inlined, meaning that code is generated for the
- function, rather than a function call. The inline keywords also implicitly
- declare the function as static.
-
- Using the inline specifiers with data generates an error.
-
- By default, function inlining is turned off, and functions qualified with
- inline specifiers are treated simply as static functions. To turn on function
- inlining, specify the /Oi+ option. If you turn optimization on (/O+), /Oi+
- becomes the default.
-
- Recursive functions (functions that call themselves) are inlined for the first
- occurrence only. The call to the function from within itself will not be
- inlined.
-
- You can also use the /Oivalue option to automatically inline all functions
- smaller than value abstract code units as well as those qualified with inline
- specifiers. For best performance, use the inline keywords to choose the
- functions you want to inline rather than using automatic inlining.
-
- When inlining is turned on, the following functions are also considered
- candidates to be inlined:
-
- C++ member functions that are defined in class declarations.
- For C programs only, small functions of static storage class that are
- called only once.
-
- Note: If you plan to debug your code (specifying /Ti+), you should turn
- inlining off. Profiling hooks are not generated for inlined functions.
-
- For more information on function inlining, see the IBM VisualAge for C++ for
- Windows User's Guide.
-
- Related Information
-
- static Storage Class Specifier
- Storage Class Specifiers
- Inline Functions
- Inline Member Functions
- /Oi option
-
-
- ΓòÉΓòÉΓòÉ 8. Statements ΓòÉΓòÉΓòÉ
-
- This section describes the following C and C++ language statements:
-
- Labels
- Block
- break
- continue
- do
- Expression
- for
- goto
- if
- Null Statement
- return
- switch
- while
-
- Related Information
-
- Scope in C
- Scope in C++
- Declarations
- Expressions and Operators
- Functions
-
-
- ΓòÉΓòÉΓòÉ 8.1. Labels ΓòÉΓòÉΓòÉ
-
- A label is an identifier that allows your program to transfer control to other
- statements within the same function. It is the only type of identifier that has
- function scope. Control is transferred to the statement following the label by
- means of the goto or switch statements.
-
- Syntax of a Labelled Statement
-
- The label is the identifier and the colon (:) character.
-
- The case and default labels can only appear within the body of a switch
- statement.
-
- comment_complete : ; /* null statement label */
- test_for_null : if (NULL == pointer)
-
- Related Information
-
- Scope in C
- Scope in C++
- goto
- switch
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Labelled Statement ΓòÉΓòÉΓòÉ
-
- A labelled statement has the form:
-
- >>ΓöÇΓöÇidentifierΓöÇΓöÇ:ΓöÇΓöÇstatementΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ 8.2. Block ΓòÉΓòÉΓòÉ
-
- A block statement, or compound statement, lets you group any number of data
- definitions, declarations, and statements into one statement. All definitions,
- declarations, and statements enclosed within a single set of braces are treated
- as a single statement. You can use a block wherever a single statement is
- allowed.
-
- Syntax of a Block Statement
-
- In C, Any definitions and declarations must come before the statements.
-
- Redefining a data object inside a nested block hides the outer object while the
- inner block runs. Defining several variables that have the same identifier can
- make a program difficult to understand and maintain. You should avoid
- redefining of identifiers within nested blocks. If a data object is usable
- within a block and its identifier is not redefined, all nested blocks can use
- that data object.
-
- Examples of Block Statements
-
- Related Information
-
- Block Scope Data Declarations
- Initialization within Block Statements
- Function Body
- auto Storage Class Specifier
- register Storage Class Specifier
- static Storage Class Specifier
- extern Storage Class Specifier
-
-
- ΓòÉΓòÉΓòÉ <hidden> Initialization within Block Statements ΓòÉΓòÉΓòÉ
-
- Initialization of an auto or register variable occurs each time the block is
- run from the beginning. If you transfer control from one block to the middle of
- another block, initializations are not always performed. You cannot initialize
- an extern variable within a block.
-
- A static local object is initialized only once, when control passes through its
- declaration for the first time. A static variable initialized with an
- expression other than a constant expression is initialized to 0 before its
- block is first entered.
-
- C++ Note: Unlike ANSI/ISO C, in C++ it is an error to jump over a declaration
- or definition containing an initializer. For example, the following code
- produces an error in C++:
-
- goto skiplabel;
- int i=3 // error, jumped over declaration of i with initializer
- skiplabel: i=4;
-
- When control exits from a block, all objects with destructors that are defined
- in the block are destroyed. The destructor for a static local object is called
- only if the object was constructed. The destructor must be called before or as
- part of the atexit function.
-
- Local variables declared in a block are also destroyed on exit. Automatic
- variables defined in a loop are destroyed at each iteration.
-
- Related Information
-
- Block Scope Data Declarations
- Block
- auto Storage Class Specifier
- register Storage Class Specifier
- static Storage Class Specifier
- extern Storage Class Specifier
- Destructors
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Block Statement ΓòÉΓòÉΓòÉ
-
- A block statement has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Γöé
- >>ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ}ΓöÇΓöÇ><
- Γö£ΓöÇtype_definitionΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓööΓöÇstatementΓöÇΓöÿ
- Γö£ΓöÇfile_scope_data_declarationΓöÇΓöÇΓöñ
- ΓööΓöÇblock_scope_data_declarationΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Block Statements ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program shows how the values of data objects change in nested
- blocks:
-
- *
- ************************************************************************/
-
- 1 /**
- 2 ** This example shows how data objects change in nested blocks.
- 3 **/
- 4 #include <stdio.h>
- 5
- 6 int main(void)
- 7 {
- 8 int x = 1; /* Initialize x to 1 */
- 9 int y = 3;
- 10
- 11 if (y > 0)
- 12 {
- 13 int x = 2; /* Initialize x to 2 */
- 14 printf("second x = %4d\n", x);
- 15 }
- 16 printf("first x = %4d\n", x);
- 17
- 18 return(0);
- 19 }
-
- /************************************************************************
- *
-
- The program produces the following output:
-
- second x = 2
- first x = 1
-
- Two variables named x are defined in main. The definition of x on line 8
- retains storage while main is running. However, because the definition of x on
- line 13 occurs within a nested block, line 14 recognizes x as the variable
- defined on line 13. Because line 16 is not part of the nested block, x is
- recognized as the variable defined on line 8.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 8.3. break ΓòÉΓòÉΓòÉ
-
- A break statement lets you end an iterative (do, for, while) or switch
- statement and exit from it at any point other than the logical end.
-
- Syntax of a break Statement
-
- In an iterative statement the break statement ends the loop and moves control
- to the next statement outside the loop. Within nested statements, the break
- statement ends only the smallest enclosing do, for, switch, or while statement.
-
- In a switch body, the break passes control out of the switch body to the next
- statement outside the switch body.
-
- A break statement can only appear in the body of an iterative statement or a
- switch statement.
-
- Examples of break Statements
-
- Related Information
-
- do
- for
- switch
- while
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a break Statement ΓòÉΓòÉΓòÉ
-
- A break statement has the form:
-
- >>ΓöÇΓöÇbreakΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of break Statements ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows a break statement in the action part of a for
- statement. If the ith element of the array string is equal to '\0', the break
- statement causes the for statement to end.
-
- for (i = 0; i < 5; i++)
- {
- if (string[i] == '\0')
- break;
- length++;
- }
-
- The following is an equivalent for statement, if string does not contain any
- embedded null characters:
-
- for (i = 0; (i < 5)&& (string[i] != '\0'); i++)
- {
- length++;
- }
-
- The following example shows a break statement in a nested iterative statement.
- The outer loop goes through an array of pointers to strings. The inner loop
- examines each character of the string. When the break statement is processed,
- the inner loop ends and control returns to the outer loop.
-
- *
- ************************************************************************/
-
- /**
- ** This program counts the characters in the strings that are
- ** part of an array of pointers to characters. The count stops
- ** when one of the digits 0 through 9 is encountered
- ** and resumes at the beginning of the next string.
- **/
-
- #include <stdio.h>
- #define SIZE 3
-
- int main(void)
- {
- static char *strings[SIZE] = { "ab", "c5d", "e5" };
- int i;
- int letter_count = 0;
- char *pointer;
-
- for (i = 0; i < SIZE; i++) /* for each string */
- /* for each character */
- for (pointer = strings[i]; *pointer != '\0'; ++pointer)
- { /* if a number */
- if (*pointer >= '0' && *pointer <= '9')
- break;
- letter_count++;
- }
- printf("letter count = %d\n", letter_count);
-
- return(0);
- }
-
- /************************************************************************
- *
-
- The program produces the following output:
-
- letter count = 4
-
- The following example is a switch statement that contains several break
- statements. Each break statement indicates the end of a specific clause and
- ends the switch statement.
-
- /**
- ** This example shows a switch statement with break statements.
- **/
-
- #include <stdio.h>
-
- enum {morning, afternoon, evening} timeofday = morning;
-
- int main(void) {
-
- switch (timeofday) {
- case (morning):
- printf("Good Morning\n");
- break;
-
- case (evening):
- printf("Good Evening\n");
- break;
-
- default:
- printf("Good Day, eh\n");
- }
- }
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 8.4. continue ΓòÉΓòÉΓòÉ
-
- A continue statement lets you end the current iteration of a loop. Program
- control is passed from the continue statement to the end of the loop body.
-
- Syntax of a continue Statement
-
- The continue statement ends the processing of the action part of an iterative
- (do, for, or while) statement and moves control to the condition part of the
- statement. If the iterative statement is a for statement, control moves to the
- third expression in the condition part of the statement, then to the second
- expression (the test) in the condition part of the statement.
-
- Within nested statements, the continue statement ends only the current
- iteration of the do, for, or while statement immediately enclosing it.
-
- A continue statement can only appear within the body of an iterative statement.
-
- Examples of continue Statements
-
- Related Information
-
- do
- for
- while
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a continue Statement ΓòÉΓòÉΓòÉ
-
- A continue statement has the form:
-
- >>ΓöÇΓöÇcontinueΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of continue Statements ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows a continue statement in a for statement. The
- continue statement causes processing to skip over those elements of the array
- rates that have values less than or equal to 1.
-
- *
- ************************************************************************/
-
- /**
- ** This example shows a continue statement in a for statement.
- **/
-
- #include <stdio.h>
- #define SIZE 5
-
- int main(void)
- {
- int i;
- static float rates[SIZE] = { 1.45, 0.05, 1.88, 2.00, 0.75 };
-
- printf("Rates over 1.00\n");
- for (i = 0; i < SIZE; i++)
- {
- if (rates[i] <= 1.00) /* skip rates <= 1.00 */
- continue;
- printf("rate = %.2f\n", rates[i]);
- }
-
- return(0);
- }
-
- /************************************************************************
- *
-
- The program produces the following output:
-
- Rates over 1.00
- rate = 1.45
- rate = 1.88
- rate = 2.00
-
- The following example shows a continue statement in a nested loop. When the
- inner loop encounters a number in the array strings, that iteration of the loop
- ends. Processing continues with the third expression of the inner loop. The
- inner loop ends when the '\0' escape sequence is encountered.
-
- *
- ************************************************************************/
-
- /**
- ** This program counts the characters in strings that are part
- ** of an array of pointers to characters. The count excludes
- ** the digits 0 through 9.
- **/
-
- #include <stdio.h>
- #define SIZE 3
-
- int main(void)
- {
- static char *strings[SIZE] = { "ab", "c5d", "e5" };
- int i;
- int letter_count = 0;
- char *pointer;
- for (i = 0; i < SIZE; i++) /* for each string */
- /* for each each character */
- for (pointer = strings[i]; *pointer != '\0'; ++pointer)
- { /* if a number */
- if (*pointer >= '0' && *pointer <= '9')
- continue;
- letter_count++;
- }
- printf("letter count = %d\n", letter_count);
-
- return(0);
- }
-
- /************************************************************************
- *
-
- The program produces the following output:
-
- letter count = 5
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 8.5. do ΓòÉΓòÉΓòÉ
-
- A do statement repeatedly runs a statement until the test expression evaluates
- to 0. Because of the order of processing, the statement is run at least once.
-
- Syntax of a do Statement
-
- The body of the loop is run before the controlling while clause is evaluated.
- Further processing of the do statement depends on the value of the while
- clause. If the while clause does not evaluate to 0, the statement runs again.
- When the while clause evaluates to 0, the statement ends. The controlling
- expression must be evaluate to a scalar type.
-
- A break, return, or goto statement can cause the processing of a do statement
- to end, even when the while clause does not evaluate to 0.
-
- Example of a do Statement
-
- Related Information
-
- break
- continue
- for
- goto
- return
- while
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a do Statement ΓòÉΓòÉΓòÉ
-
- A do statement has the form:
-
- >>ΓöÇΓöÇdoΓöÇΓöÇstatementΓöÇΓöÇwhileΓöÇΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a do Statement ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following statement prompts the user to enter a 1. If the user enters a 1,
- the statement ends. If not, it displays another prompt.
-
- *
- ************************************************************************/
- The example contains error-checking code to verify that the user entered an
- integer value and to clear the input stream if an error occurs.
-
- /**
- ** This example illustrates the do statement.
- **/
-
- #include <iostream.h>
- void main()
- {
- int reply1;
- char c;
- do
- {
- cout << "Enter a 1: ";
- cin >> reply1;
- if (cin.fail())
- {
- cerr << "Not a valid number." << endl;
- // Clear the error flag.
- cin.clear(cin.rdstate() & ~ios::failbit);
- // Purge incorrect input.
- cin.ignore(cin.rdbuf()->in_avail());
- }
- }
- while (reply1 != 1);
- }
-
-
- ΓòÉΓòÉΓòÉ 8.6. Expression ΓòÉΓòÉΓòÉ
-
- An expression statement contains an expression. The expression can be null.
- Expressions are described in Expressions and Operators.
-
- Syntax of an Expression Statement
-
- An expression statement evaluates the given expression. It is used to assign
- the value of the expression to a variable or to call a function.
-
- The following are examples of expressions:
-
- printf("Account Number: \n"); /* call to the printf */
- marks = dollars * exch_rate; /* assignment to marks */
- (difference < 0) ? ++losses : ++gain; /* conditional increment */
- switches = flags Γûî BIT_MASK; /* assignment to switches */
-
- Resolving Ambiguous Statements in C++
-
-
- ΓòÉΓòÉΓòÉ 8.7. Resolving Ambiguous Statements in C++ ΓòÉΓòÉΓòÉ
-
- There are situations in C++ where a statement can be parsed as both a
- declaration and as an expression. Specifically, a declaration can look like a
- function call in certain cases. The compiler resolves these ambiguities by
- applying the following rules to the whole statement:
-
- If the statement can be parsed as a declaration but there are no
- declaration specifiers in the declaration and the statement is inside the
- body of a function, the statement is assumed to be an expression.
-
- The following statement, for example, is a declaration at file scope of
- the function f() that returns type int. There is no declaration specifier
- and int is the default, but at function scope this is a call to f():
-
- f();
-
- In every other case, if the statement can be parsed as a declaration, it
- is assumed to be a declaration. The following statement, for example, is
- a declaration of x with redundant parentheses around the declarator, not
- a function-style cast of x to type int:
-
- int (x);
-
- In some cases, C++ syntax does not disambiguate between expression statements
- and declaration statements. The ambiguity arises when an expression statement
- has a function-style cast as its leftmost subexpression. (Note that, because C
- does not support function-style casts, this ambiguity does not occur in C
- programs.) If the statement can be interpreted both as a declaration and as an
- expression, the statement is interpreted as a declaration statement.
-
- Note: The ambiguity is resolved only on a syntactic level. The disambiguation
- does not use the meaning of the names, except to assess whether or not they
- are type names.
-
- The following expressions disambiguate into expression statements because the
- ambiguous subexpression is followed by an assignment or an operator. type_spec
- in the expressions can be any type specifier:
-
- type_spec(i)++; // expression statement
- type_spec(i,3)<<d; // expression statement
- type_spec(i)->l=24; // expression statement
-
- In the following examples, the ambiguity cannot be resolved syntactically, and
- the statements are interpreted as declarations. type_spec is any type
- specifier:
-
- type_spec(*i)(int); // declaration
- type_spec(j)[5]; // declaration
- type_spec(m) = { 1, 2 }; // declaration
- type_spec(*k) (float(3)); // declaration
-
- The last statement above causes a compile-time error because you cannot
- initialize a pointer with a float value.
-
- Any ambiguous statement that is not resolved by the above rules is by default
- a declaration statement. All of the following are declaration statements:
-
- type_spec(a); // declaration
- type_spec(*b)(); // declaration
- type_spec(c)=23; // declaration
- type_spec(d),e,f,g=0; // declaration
- type_spec(h)(e,3); // declaration
-
- Another C++ ambiguity between expression statements and declaration statements
- is resolved by requiring an explicit return type for function declarations
- within a block:
-
- a(); // declaration of a function returning int
- // and taking no arguments
- void func()
- {
- int a(); // declaration of a function
- int b; // declaration of a variable
- a(); // expression-statement calling function a()
- b; // expression-statement referring to a variable
- }
-
- The last statement above does not produce any action. It is semantically
- equivalent to a null statement. However, it is a valid C++ statement.
-
- Related Information
-
- Function Declarations
- Cast Expressions
-
- Related Information
-
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of an Expression Statement ΓòÉΓòÉΓòÉ
-
- An expression statement has the form:
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ;ΓöÇΓöÇ><
- ΓööΓöÇexpressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 8.8. for ΓòÉΓòÉΓòÉ
-
- A for statement lets you do the following:
-
- Evaluate an expression before the first iteration of the statement
- (initialization)
- Specify an expression to determine whether or not the statement should be
- processed (controlling part)
- Evaluate an expression after each iteration of the statement
- Repeatedly process the statement if the controlling part does not
- evaluate to zero.
-
- Syntax of a for Statement
-
- A break, return, or goto statement can cause a for statement to end, even when
- the second expression does not evaluate to 0. If you omit expression2, you
- must use a break, return, or goto statement to end the for statement.
-
- C++ Note: In C++ programs, you can also use expression1 to declare a variable
- as well as initialize it. If you declare a variable in this expression, the
- variable has the same scope as the for statement and is not local to the for
- statement.
-
- Examples of for Statements
-
- Related Information
-
- break
- continue
- do
- return
- goto
- while
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a for Statement ΓòÉΓòÉΓòÉ
-
- A for statement has the form:
-
- >>ΓöÇΓöÇforΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ;ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ;ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ>
- ΓööΓöÇexpression1ΓöÇΓöÿ ΓööΓöÇexpression2ΓöÇΓöÿ ΓööΓöÇexpression3ΓöÇΓöÿ
- >ΓöÇΓöÇstatementΓöÇΓöÇ><
-
- Expression1 Is the initialization expression. It is evaluated only before
- the statement is processed for the first time. You can use
- this expression to initialize a variable. If you do not want
- to evaluate an expression prior to the first iteration of the
- statement, you can omit this expression.
-
- Expression2 Is the controlling part. It is evaluated before each iteration
- of the statement. It must evaluate to a scalar type.
-
- If it evaluates to 0 (zero), the statement is not processed
- and control moves to the next statement following the for
- statement. If expression2 does not evaluate to 0, the
- statement is processed. If you omit expression2, it is as if
- the expression had been replaced by a nonzero constant, and
- the for statement is not terminated by failure of this
- condition.
-
- Expression3 Is evaluated after each iteration of the statement. You can
- use this expression to increase, decrease, or reinitialize a
- variable. This expression is optional.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of for Statements ΓòÉΓòÉΓòÉ
-
- The following for statement prints the value of count 20 times. The for
- statement initially sets the value of count to 1. After each iteration of the
- statement, count is incremented.
-
- for (count = 1; count <= 20; count++)
- printf("count = %d\n", count);
-
- The following sequence of statements accomplishes the same task. Note the use
- of the while statement instead of the for statement.
-
- count = 1;
- while (count <= 20)
- {
- printf("count = %d\n", count);
- count++;
- }
-
- The following for statement does not contain an initialization expression:
-
- for (; index > 10; --index)
- {
- list[index] = var1 + var2;
- printf("list[%d] = %d\n", index, list[index]);
- }
-
- The following for statement will continue running until scanf receives the
- letter e:
-
- for (;;)
- {
- scanf("%c", &letter);
- if (letter == '\n')
- continue;
- if (letter == 'e')
- break;
- printf("You entered the letter %c\n", letter);
- }
-
- The following for statement contains multiple initializations and increments.
- The comma operator makes this construction possible. The first comma in the for
- expression is a punctuator for a declaration. It declares and initializes two
- integers, i and j. The second comma, a comma operator, allows both i and j to
- be incremented at each step through the loop.
-
- for (int i = 0, j = 50; i < 10; ++i, j += 50)
- {
- cout << "i = " << i << "and j = " << j << endl;
- }
-
- The following example shows a nested for statement. It prints the values of an
- array having the dimensions [5][3].
-
- for (row = 0; row < 5; row++)
- for (column = 0; column < 3; column++)
- printf("%d\n", table[row][column]);
-
- The outer statement is processed as long as the value of row is less than 5.
- Each time the outer for statement is executed, the inner for statement sets the
- initial value of column to zero and the statement of the inner for statement is
- executed 3 times. The inner statement is executed as long as the value of
- column is less than 3.
-
-
- ΓòÉΓòÉΓòÉ 8.9. goto ΓòÉΓòÉΓòÉ
-
- A goto statement causes your program to unconditionally transfer control to the
- statement associated with the label specified on the goto statement.
-
- Syntax of a goto Statement
-
- Because the goto statement can interfere with the normal sequence of
- processing, it makes a program more difficult to read and maintain. Often, a
- break statement, a continue statement, or a function call can eliminate the
- need for a goto statement.
-
- If you use a goto statement to transfer control to a statement inside of a loop
- or block, initializations of automatic storage for the loop do not take place
- and the result is undefined. The label must appear in the same function as the
- goto.
-
- If an active block is exited using a goto statement, any local variables are
- destroyed when control is transferred from that block.
-
- Example of a goto Statement
-
- Related Information
-
- Labels
- break
- continue
- Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a goto Statement ΓòÉΓòÉΓòÉ
-
- A goto statement has the form:
-
- >>ΓöÇΓöÇgotoΓöÇΓöÇlabel_identifierΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a goto Statement ΓòÉΓòÉΓòÉ
-
- The following example shows a goto statement that is used to jump out of a
- nested loop. This function could be written without using a goto statement.
-
- /**
- ** This example shows a goto statement that is used to
- ** jump out of a nested loop.
- **/
-
- #include <stdio.h>
- void display(int matrix[3][3]);
-
- int main(void)
- {
- int matrix[3][3]={1,2,3,4,5,2,8,9,10};
- display(matrix);
- return(0);
- }
-
- void display(int matrix[3][3])
- {
- int i, j;
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- {
- if ( (matrix[i][j] < 1) ΓûîΓûî (matrix[i][j] > 6) )
- goto out_of_bounds;
- printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j]);
- }
- return;
- out_of_bounds: printf("number must be 1 through 6\n");
- }
-
-
- ΓòÉΓòÉΓòÉ 8.10. if ΓòÉΓòÉΓòÉ
-
- An if statement lets you conditionally process a statement when the specified
- test expression evaluates to a nonzero value. The expression must evaluate to a
- scalar type. You can optionally specify an else clause on the if statement. If
- the test expression evaluates to 0 and an else clause exists, the statement
- associated with the else clause runs. If the test expression evaluates to a
- nonzero value, the statement following the expression runs and the else clause
- is ignored.
-
- Syntax of an if Statement
-
- When if statements are nested and else clauses are present, a given else is
- associated with the closest preceding if statement within the same block.
-
- Examples of if Statements
-
- Related Information
-
- Conditional Compilation Directives
- switch
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of an if Statement ΓòÉΓòÉΓòÉ
-
- An if statement has the form:
-
- >>ΓöÇΓöÇifΓöÇΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇstatementΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇelseΓöÇΓöÇstatementΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of if Statements ΓòÉΓòÉΓòÉ
-
- The following example causes grade to receive the value A if the value of score
- is greater than or equal to 90.
-
- if (score >= 90)
- grade = 'A';
-
- The following example displays Number is positive if the value of number is
- greater than or equal to 0. If the value of number is less than 0, it displays
- Number is negative.
-
- if (number >= 0)
- printf("Number is positive\n");
- else
- printf("Number is negative\n");
-
- The following example shows a nested if statement:
-
- if (paygrade == 7)
- if (level >= 0 && level <= 8)
- salary *= 1.05;
- else
- salary *= 1.04;
- else
- salary *= 1.06;
- cout << "salary is " << salary << endl;
-
- The following example shows a nested if statement that does not have an else
- clause. Because an else clause always associates with the closest if statement,
- braces might be needed to force a particular else clause to associate with the
- correct if statement. In this example, omitting the braces would cause the else
- clause to associate with the nested if statement.
-
- if (kegs > 0) {
- if (furlongs > kegs)
- fpk = furlongs/kegs;
- }
- else
- fpk = 0;
-
- The following example shows an if statement nested within an else clause. This
- example tests multiple conditions. The tests are made in order of their
- appearance. If one test evaluates to a nonzero value, a statement runs and the
- entire if statement ends.
-
- if (value > 0)
- ++increase;
- else if (value == 0)
- ++break_even;
- else
- ++decrease;
-
-
- ΓòÉΓòÉΓòÉ 8.11. Null Statement ΓòÉΓòÉΓòÉ
-
- The null statement performs no operation.
-
- Syntax of a Null Statement
-
- A null statement can hold the label of a labeled statement or complete the
- syntax of an iterative statement.
-
- The following example initializes the elements of the array price. Because the
- initializations occur within the for expressions, a statement is only needed to
- finish the for syntax; no operations are required.
-
- for (i = 0; i < 3; price[i++] = 0)
- ;
-
- A null statement can be used when a label is needed before the end of a block
- statement. For example:
-
- void func(void) {
- if (error_detected)
- goto depart;
- /* further processing */
- depart: ; /* null statement required */
- }
-
- Related Information
-
- Null Directive (#)
- Labels
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Null Statement ΓòÉΓòÉΓòÉ
-
- A null statement has the form:
-
- >>ΓöÇΓöÇ;ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ 8.12. return ΓòÉΓòÉΓòÉ
-
- A return statement ends the processing of the current function and returns
- control to the caller of the function.
-
- Syntax of a return Statement
-
- A return statement in a function is optional. The compiler issues a warning if
- a return statement is not found in a function declared with a return type. If
- the end of a function is reached without encountering a return statement,
- control is passed to the caller as if a return statement without an expression
- were encountered. A function can contain multiple return statements.
-
- If an expression is present on a return statement, the value of the expression
- is returned to the caller. If the data type of the expression is different from
- the function return type, conversion of the return value takes place as if the
- value of the expression were assigned to an object with the same function
- return type.
-
- If an expression is not present on a return statement, the value of the return
- statement is undefined. If an expression is not given on a return statement in
- a function declared with a nonvoid return type, an error message is issued, and
- the result of calling the function is unpredictable. For example:
-
- int func1()
- {
- return;
- }
- int func2()
- {
- return (4321);
- }
-
- void main() {
- int a=func1(); // result is unpredictable!
- int b=func2();
- }
-
- You cannot use a return statement with an expression when the function is
- declared as returning type void.
-
- You can use the /Wret compiler option to generate diagnostic messages about the
- use of return statements in your functions.
-
- C++ Note: If a function returns a class object with constructors, a temporary
- class object might be constructed. The temporary object is not in the scope of
- the function returning the temporary object but is local to the caller of the
- function.
-
- When a function returns, all temporary local variables are destroyed. If local
- class objects with destructors exist, destructors are called. For more details,
- see Temporary Objects.
-
- Examples of return Statements
-
- Related Information
-
- Functions
- /W option
- Expression
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a return Statement ΓòÉΓòÉΓòÉ
-
- A return statement has the form:
-
- >>ΓöÇΓöÇreturnΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ;ΓöÇΓöÇ><
- ΓööΓöÇexpressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of return Statements ΓòÉΓòÉΓòÉ
-
- return; /* Returns no value */
- return result; /* Returns the value of result */
- return 1; /* Returns the value 1 */
- return (x * x); /* Returns the value of x * x */
-
- The following function searches through an array of integers to determine if a
- match exists for the variable number. If a match exists, the function match
- returns the value of i. If a match does not exist, the function match returns
- the value -1 (negative one).
-
- int match(int number, int array[ ], int n)
- {
- int i;
-
- for (i = 0; i < n; i++)
- if (number == array[i])
- return (i);
- return(-1);
- }
-
-
- ΓòÉΓòÉΓòÉ 8.13. Structured Exception Handling Statements ΓòÉΓòÉΓòÉ
-
- Structured Exception Handling (SEH) is a Windows-specific mechanism for
- handling system exceptions.
-
- Note: SEH is only available in the C compiler.
-
- SEH is different from C++ exception handling. C++ matches exceptions based on
- the type of the expression that is thrown. It does not allow resumption of
- execution after the exception. SEH matches exceptions with handlers based on
- the value returned from a filter expression. It can be resumptive or
- nonresumptive, and can catch any operating system exception. Unlike C++
- exception handling, it is not portable; it is only available with the Win32
- API.
-
- Structured exception handling consists of two parts:
-
- Termination handling with try-finally
- Exception handling with try-except
-
- See the IBM VisualAge for C++ for Windows Programming Guide for detailed
- information about using structured exception handling with other error
- handling mechanisms.
-
-
- ΓòÉΓòÉΓòÉ 8.13.1. Try-Finally Termination Handling ΓòÉΓòÉΓòÉ
-
- Termination handling is performed using a try-finally block:
-
- >>ΓöÇΓöÇ__tryΓöÇΓöÇblock_statementΓöÇΓöÇ__finallyΓöÇΓöÇblock_statementΓöÇΓöÇ><
-
- A termination handler has this structure:
-
- // 1. Code before try block
- // ...
- __try {
- // 2. Guarded body
- // ...
- }
- __finally {
- // 3. termination handler
- // ...
- }
- // 4. Code after the termination handler
- // ...
-
- The numbered comments indicate the order of execution.
-
- Termination handling guarantees that one block of code, called the termination
- handler, will be run no matter how another block, referred to as the guarded
- body, is exited. Regardless of whether the gaurded body runs normally or
- encounters an exception, exits because of a break, continue, goto, or return,
- or for some other reason, the termination handler is always be executed.
-
- Termination handlers are useful for simplifying error handling by moving all
- cleanup code into a common place. This improves program readability, and
- reduces maintenance. They are typically used for managing memory, closing file
- handles, and releasing semaphores.
-
-
- ΓòÉΓòÉΓòÉ 8.13.2. Try-Except Structured Exception Handling ΓòÉΓòÉΓòÉ
-
- Exception handling is performed using a try-except block:
-
- >>ΓöÇΓöÇ__tryΓöÇΓöÇblock_statementΓöÇΓöÇ__exceptΓöÇΓöÇ(ΓöÇΓöÇexception_filterΓöÇΓöÇ)ΓöÇΓöÇ>
- >ΓöÇΓöÇblock_statementΓöÇΓöÇ><
-
- An exception handler has this structure:
-
- // 1. Code before try block
- // ...
- __try {
- // 2. Guarded body
- // ...
- }
- __except( filter /* 3. exception filter */ ) {
- // 4. Exception handler
- // ...
- }
- // 5. Code after the exception handler
- // ...
-
- The actual order of execution depends on the evaluation of the exception
- filter. The example above illustrates an exception in the guarded body where
- the exception filter has evaluated to EXCEPTION_EXECUTE_HANDLER. If no
- exception occurs in the guarded body the except block is not reached and the
- code after the exception handler is run.
-
- You must use the header <excpt.h>, which contains the data structure
- definitions for an exception. There can be no code between the try and the
- except or finally blocks. A try block also can only have one finally or except
- block associated with it. You can nest try-finally blocks inside try-except
- blocks and vice versa.
-
- When an exception is generated, the system locates the beginning of the except
- block and evaluates an an exception filter that you provide. It must evaluate
- to one of three values defined by the following macro names:
-
- EXCEPTION_EXECUTE_HANDLER 1
-
- EXCEPTION_CONTINUE_EXECUTION -1
-
- EXCEPTION_CONTINUE_SEARCH 0
-
- The exception filter can be a function, a constant, or an expression.
-
- The filter compares the exception with the list of exception signals in the
- <winnt.h> header. If your filter finds a match, it should evaluate to the
- value of EXCEPTION_EXECUTE_HANDLER (1), which causes your exception handler to
- be executed. This results in a global unwind, which causes all outstanding
- try-finally blocks below the try-except block to be run. After the exception
- handler is executed, control resumes at the first instruction after the except
- block. The global unwind process is described in detail in the IBM VisualAge
- for C++ for Windows Programming Guide.
-
- If your filter evaluates to the value of EXCEPTION_CONTINUE_EXECUTION (-1),
- then you are indicating that you have taken care of the exception and that the
- execution continues from the instruction that generated the exception.
- Usually, the exception is repaired in the filter, and -1 is returned. However,
- this is not guaranteed always to work exactly as expected since it depends on
- the machine encoding. More than one instruction may be used to encode a single
- line of code, and the specific machine instruction that caused the exception
- may not have a value that has been repaired. This may cause an infinite loop.
-
- If your exception filter evaluates to the value of EXCEPTION_CONTINUE_SEARCH
- (0), the system looks for another exception handler by searching backwards
- through the call stack. for the most-recently executing try-except block and
- calls its exception filter. It ignores any try-finally blocks. If none is
- found, it calls the system exception handler for an unhandled exception.
-
-
- ΓòÉΓòÉΓòÉ 8.13.3. Precedence of Exception Handler Registration ΓòÉΓòÉΓòÉ
-
- If a function has both a #pragma handler registered for it and structured
- exception handling code in the function body, the #pragma handler is registered
- first. This allows the structured exception handlers to override both the
- default _Exception handler and your own handlers.
-
- See handler for the description of the #pragma handler directive.
-
-
- ΓòÉΓòÉΓòÉ 8.14. switch ΓòÉΓòÉΓòÉ
-
- A switch statement lets you transfer control to different statements within the
- switch body depending on the value of the switch expression. The switch
- expression must evaluate to an integral value. The body of the switch statement
- contains case clauses that consist of
-
- A case label
- An optional default label
- A case expression
- A list of statements.
-
- If the value of the switch expression equals the value of one of the case
- expressions, the statements following that case expression are processed. If
- not, the default label statements, if any, are processed.
-
- A switch statement has the form:
-
- >>ΓöÇΓöÇswitchΓöÇΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇswitch_bodyΓöÇΓöÇ><
-
- Syntax of a switch Body
-
- A case clause contains a case label followed by any number of statements.
-
- A case label contains the word case followed by an integral constant
- expression and a colon. Anywhere you can put one case label, you can put
- multiple case labels.
-
- A default clause contains a default label followed by one or more statements.
- You can put a case label on either side of the default label. A switch
- statement can have only one default label.
-
- The switch statement passes control to the statement following one of the
- labels or to the statement following the switch body. The value of the
- expression that precedes the switch body determines which statement receives
- control. This expression is called the switch expression.
-
- The value of the switch expression is compared with the value of the
- expression in each case label. If a matching value is found, control is passed
- to the statement following the case label that contains the matching value. If
- there is no matching value but there is a default label in the switch body,
- control passes to the default labelled statement. If no matching value is
- found, and there is no default label anywhere in the switch body, no part of
- the switch body is processed.
-
- When control passes to a statement in the switch body, control only leaves the
- switch body when a break statement is encountered or the last statement in the
- switch body is processed.
-
- If necessary, an integral promotion is performed on the controlling
- expression, and all expressions in the case statements are converted to the
- same type as the controlling expression.
-
- Restrictions
- The switch expression and the case expressions must have an integral type. The
- value of each case expression must represent a different value and must be a
- constant expression.
-
- Only one default label can occur in each switch statement. You cannot have
- duplicate case labels in a switch statement.
-
- You can put data definitions at the beginning of the switch body, but the
- compiler does not initialize auto and register variables at the beginning of a
- switch body.
-
- C++ Note: You can have declarations in the body of the switch statement. In
- C++, you cannot transfer control over a declaration containing an initializer
- unless the declaration is located in an inner block that is completely
- bypassed by the transfer of control. All declarations within the body of a
- switch statement that contain initializers must be contained in an inner
- block.
-
- Examples of switch Statements
-
- Related Information
-
- break
- if
- Labels
- Expression
- Type Specifiers
- Storage Class Specifiers
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a switch Body ΓòÉΓòÉΓòÉ
-
- The switch body is enclosed in braces and can contain definitions,
- declarations, case clauses, and a default clause. Each case clause and default
- clause can contain statements.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Γöé
- >>ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ>
- Γö£ΓöÇtype_definitionΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ ΓööΓöÇcase_clauseΓöÇΓöÿ
- Γö£ΓöÇfile_scope_data_declarationΓöÇΓöÇΓöñ
- ΓööΓöÇblock_scope_data_declarationΓöÇΓöÿ
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ}ΓöÇΓöÇ><
- ΓööΓöÇdefault_clauseΓöÇΓöÿ ΓööΓöÇcase_clauseΓöÇΓöÿ
-
- A case clause has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇcase_labelΓöÇΓöÇΓöÇΓöÇstatementΓöÇΓö┤ΓöÇΓöÇ><
-
- A case label has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓöÇΓöÇcaseΓöÇΓöÇintegral_constant_expressionΓöÇΓöÇ:ΓöÇΓö┤ΓöÇΓöÇ><
-
- A default clause has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇdefaultΓöÇΓöÇ:ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇstatementΓöÇΓö┤ΓöÇΓöÇ><
- ΓööΓöÇcase_labelΓöÇΓöÿ ΓööΓöÇcase_labelΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of switch Statements ΓòÉΓòÉΓòÉ
-
- The following switch statement contains several case clauses and one default
- clause. Each clause contains a function call and a break statement. The break
- statements prevent control from passing down through each statement in the
- switch body.
-
- If the switch expression evaluated to '/', the switch statement would call the
- function divide. Control would then pass to the statement following the switch
- body.
-
- char key;
-
- cout << "Enter an arithmetic operator\n");
- cin >> key;
-
- switch (key)
- {
- case '+':
- add();
- break;
-
- case '-':
- subtract();
- break;
-
- case '*':
- multiply();
- break;
-
- case '/':
- divide();
- break;
-
- default:
- cout << "The key you pressed is not valid\n";
- break;
- }
-
- If the switch expression matches a case expression, the statements following
- the case expression are processed until a break statement is encountered or the
- end of the switch body is reached. In the following example, break statements
- are not present. If the value of text[i] is equal to 'A', all three counters
- are incremented. If the value of text[i] is equal to 'a', lettera and total are
- increased. Only total is increased if text[i] is not equal to 'A' or 'a'.
-
- char text[100];
- int capa, lettera, total;
-
- for (i=0; i<sizeof(text); i++) {
-
- switch (text[i])
- {
- case 'A':
- capa++;
- case 'a':
- lettera++;
- default:
- total++;
- }
- }
-
- The following switch statement performs the same statements for more than one
- case label:
-
- /**
- ** This example contains a switch statement that performs
- ** the same statement for more than one case label.
- **/
-
- #include <stdio.h>
-
- int main(void)
- {
- int month;
-
- /* Read in a month value */
- printf("Enter month: ");
- scanf("%d", &month);
-
- /* Tell what season it falls into */
- switch (month)
- {
- case 12:
- case 1:
- case 2:
- printf("month %d is a winter month\n", month);
- break;
-
- case 3:
- case 4:
- case 5:
- printf("month %d is a spring month\n", month);
- break;
-
- case 6:
- case 7:
- case 8:
- printf("month %d is a summer month\n", month);
- break;
-
- case 9:
- case 10:
- case 11:
- printf("month %d is a fall month\n", month);
- break;
-
- case 66:
- case 99:
- default:
- printf("month %d is not a valid month\n", month);
- }
-
- return(0);
- }
-
- If the expression month has the value 3, control passes to the statement:
-
- printf("month %d is a spring month\n", month);
-
- The break statement passes control to the statement following the switch body.
-
-
- ΓòÉΓòÉΓòÉ 8.15. while ΓòÉΓòÉΓòÉ
-
- A while statement repeatedly runs the body of a loop until the controlling
- expression evaluates to 0.
-
- Syntax of a while Statement
-
- The expression is evaluated to determine whether or not to process the body of
- the loop. The expression must be convertible to a scalar type. If the
- expression evaluates to 0, the body of the loop never runs. If the expression
- does not evaluate to 0, the loop body is processed. After the body has run,
- control passes back to the expression. Further processing depends on the value
- of the condition.
-
- A break, return, or goto statement can cause a while statement to end, even
- when the condition does not evaluate to 0.
-
- Example of a while Statement
-
- Related Information
-
- break
- continue
- do
- for
- goto
- return
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a while Statement ΓòÉΓòÉΓòÉ
-
- A while statement has the form:
-
- >>ΓöÇΓöÇwhileΓöÇΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇstatementΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a while Statement ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following program, item[index] triples each time the value of the
- expression ++index is less than MAX_INDEX. When ++index evaluates to MAX_INDEX,
- the while statement ends.
-
- *
- ************************************************************************/
-
- /**
- ** This example illustrates the while statement.
- **/
-
- #define MAX_INDEX (sizeof(item) / sizeof(item[0]))
- #include <stdio.h>
-
- int main(void)
- {
- static int item[ ] = { 12, 55, 62, 85, 102 };
- int index = 0;
-
- while (index < MAX_INDEX)
- {
- item[index] *= 3;
- printf("item[%d] = %d\n", index, item[index]);
- ++index;
- }
-
- return(0);
- }
-
-
- ΓòÉΓòÉΓòÉ 9. Preprocessor Directives ΓòÉΓòÉΓòÉ
-
- This section describes the VisualAge for C++ preprocessor directives.
- Preprocessing is a step that takes place before compilation that lets you:
-
- Replace tokens in the current file with specified replacement tokens.
- Imbed files within the current file
- Conditionally compile sections of the current file
- Generate diagnostic messages
- Change the line number of the next line of source and change the file
- name of the current file.
-
- A token is a series of characters delimited by white space. The only white
- space allowed on a preprocessor directive is the space, horizontal tab,
- vertical tab, form feed, and comments. The new-line character can also
- separate preprocessor tokens.
-
- The preprocessed source program file must be a valid C or C++ program.
-
- The preprocessor is controlled by the following directives:
-
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
- Preprocessor Error Directive (#error)
- File Inclusion (#include)
- #if, #elif
- #ifdef
- #ifndef
- #else
- #endif
- Line Control (#line)
- Pragma Directives (#pragma)
-
- This section also describes:
-
- The # operator
- Macro concatenation with the ## operator
- The null directive (#)
- Predefined macros.
-
- Related Information
-
- The format of a preprocessor directive
-
-
- ΓòÉΓòÉΓòÉ 9.1. Preprocessor Directive Format ΓòÉΓòÉΓòÉ
-
- Preprocessor directives begin with the # token followed by a preprocessor
- keyword. The # token must appear as the first character that is not white space
- on a line. The # is not part of the directive name and can be separated from
- the name with white spaces.
-
- A preprocessor directive ends at the new-line character unless the last
- character of the line is the \ (backslash) character. If the \ character
- appears as the last character in the preprocessor line, the preprocessor
- interprets the \ and the new-line character as a continuation marker. The
- preprocessor deletes the \ (and the following new-line character) and splices
- the physical source lines into continuous logical lines.
-
- Except for some #pragma directives, preprocessor directives can appear anywhere
- in a program.
-
- Related Information
-
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.2. Phases of Preprocessing ΓòÉΓòÉΓòÉ
-
- Preprocessing appears as if it occurs in several phases.
-
- 1. New-line characters are introduced as needed to replace system-dependent
- end-of-line indicators, and any other system-dependent character-set
- translations are done. Equivalent single characters replace trigraph
- sequences.
-
- 2. Each \ (backslash) followed by a new-line character pair is deleted. The
- next source line is appended to the line that contained the sequence.
-
- 3. The source text is decomposed into preprocessing tokens and sequences of
- white space. A single white space replaces each comment. A source file
- cannot end with a partial token or comment.
-
- 4. Preprocessing directives are executed, and macros are expanded.
-
- 5. Escape sequences in character constants and string literals are replaced
- by their equivalent values.
-
- 6. Adjacent string literals are concatenated.
-
- The rest of the compilation process operates on the preprocessor output, which
- is syntactically and semantically analyzed and translated, and then linked as
- necessary with other programs and libraries.
-
-
- ΓòÉΓòÉΓòÉ 9.3. Macro Definition and Expansion (#define) ΓòÉΓòÉΓòÉ
-
- A preprocessor define directive directs the preprocessor to replace all
- subsequent occurrences of a macro with specified replacement tokens.
-
- A preprocessor #define directive has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇdefineΓöÇΓöÇidentifierΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ><
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé Γö£ΓöÇidentifierΓöÇΓöñ
- Γöé Γöé Γöé Γöé Γöé
- ΓööΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ)ΓöÇΓöÿ ΓööΓöÇcharacterΓöÇΓöÇΓöÿ
- ΓööΓöÇidentifierΓöÇΓöÿ
-
- The #define directive can contain an object-like definition or a function-like
- definition
-
- Arguments of the # and ## operators are converted before replacement of
- parameters in a function-like macro.
-
- The number of arguments in a macro invocation must be the same as the number of
- parameters in the corresponding macro definition.
-
- Commas in the macro invocation argument list do not act as argument separators
- when they are:
-
- in character constants
- in string literals
- surrounded by parentheses.
-
- Once defined, a preprocessor identifier remains defined and in scope
- independent of the scoping rules of the language. The scope of a macro
- definition begins at the definition and does not end until a corresponding
- #undef directive is encountered. If there is no corresponding #undef
- directive, the scope of the macro definition lasts until the end of the
- compilation unit.
-
- A recursive macro is not fully expanded. For example, the definition
-
- #define x(a,b) x(a+1,b+1) + 4
-
- expands x(20,10) to x(20+1,10+1) + 4 rather than trying to expand the
- macro x over and over within itself. After the macro x is expanded, it is a
- call to function x().
-
- A definition is not required to specify replacement tokens. The following
- definition removes all instances of the token debug from subsequent lines in
- the current file:
-
- #define debug
-
- You can change the definition of a defined identifier or macro with a second
- preprocessor #define directive only if the second preprocessor #define
- directive is preceded by a preprocessor #undef directive, described in Scope
- of Macro Names (#undef). The #undef directive nullifies the first definition
- so that the same identifier can be used in a redefinition.
-
- You can also use the /D compiler option to define macros on the command line.
- Macros defined on the command line override macros defined in the source code.
- The /D option is described in the IBM VisualAge for C++ for Windows User's
- Guide.
-
- Within the text of the program, the preprocessor does not scan character
- constants or string constants for macro invocations.
-
- Examples of #define Directives
-
- Related Information
-
- Object-Like Macros
- Function-Like Macros
- Scope of Macro Names (#undef)
- # Operator
- Macro Concatenation with the ## and /**/ Operators
-
-
- ΓòÉΓòÉΓòÉ 9.3.1. Object-Like Macros ΓòÉΓòÉΓòÉ
-
- An object-like macro definition replaces a single identifier with the specified
- replacement tokens. The following object-like definition causes the
- preprocessor to replace all subsequent instances of the identifier COUNT with
- the constant 1000:
-
- #define COUNT 1000
-
- If the statement
-
- int arry[COUNT];
-
- appears after this definition and in the same file as the definition, the
- preprocessor would change the statement to
-
- int arry[1000];
-
- in the output of the preprocessor.
-
- Other definitions can make reference to the identifier COUNT:
-
- #define MAX_COUNT COUNT + 100
-
- The preprocessor replaces each subsequent occurrence of MAX_COUNT with
- COUNT + 100, which the preprocessor then replaces with 1000 + 100.
-
- If a number that is partially built by a macro expansion is produced, the
- preprocessor does not consider the result to be a single value. For example,
- the following will not result in the value 10.2 but in a syntax error.
-
- #define a 10
- a.2
-
- Using the following also results in a syntax error:
-
- #define a 10
- #define b a.11
-
- Identifiers that are partially built from a macro expansion may not be
- produced. Therefore, the following example contains two identifiers and results
- in a syntax error:
-
- #define d efg
- abcd
-
-
- ΓòÉΓòÉΓòÉ 9.3.2. Function-Like Macros ΓòÉΓòÉΓòÉ
-
- Function-like macro definition:
- An identifier followed by a parenthesized parameter list in parenthesis
- and the replacement tokens. The parameters are imbedded in the
- replacement code. White space cannot separate the identifier (which is
- the name of the macro) and the left parenthesis of the parameter list. A
- comma must separate each parameter. For portability, you should not have
- more than 31 parameters for a macro.
-
- Function-like macro invocation:
- An identifier followed by a list of arguments in parentheses. A comma
- must separate each argument. Once the preprocessor identifies a
- function-like macro invocation, argument substitution takes place. A
- parameter in the replacement code is replaced by the corresponding
- argument. Any macro invocations contained in the argument itself are
- completely replaced before the argument replaces its corresponding
- parameter in the replacement code.
-
- The following line defines the macro SUM as having two parameters a and b and
- the replacement tokens (a + b):
-
- #define SUM(a,b) (a + b)
-
- This definition would cause the preprocessor to change the following
- statements (if the statements appear after the previous definition):
-
- c = SUM(x,y);
- c = d * SUM(x,y);
-
- In the output of the preprocessor, these statements would appear as:
-
- c = (x + y);
- c = d * (x + y);
-
- Use parentheses to ensure correct evaluation of replacement text. For example,
- the definition:
-
- #define SQR(c) ((c) * (c))
-
- requires parentheses around each parameter c in the definition in order to
- correctly evaluate an expression like:
-
- y = SQR(a + b);
-
- The preprocessor expands this statement to:
-
- y = ((a + b) * (a + b));
-
- Without parentheses in the definition, the correct order of evaluation is not
- preserved, and the preprocessor output is:
-
- y = (a + b * a + b);
-
- See Operator Precedence and Associativity, and Parenthesized Expressions ( )
- for more information about using parentheses.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of #define Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program contains two macro definitions and a macro invocation
- that refers to both of the defined macros:
-
- *
- ************************************************************************/
-
- /**
- ** This example illustrates #define directives.
- **/
-
- #include <stdio.h>
-
- #define SQR(s) ((s) * (s))
- #define PRNT(a,b) \
- printf("value 1 = %d\n", a); \
- printf("value 2 = %d\n", b) ;
-
- int main(void)
- {
- int x = 2;
- int y = 3;
-
- PRNT(SQR(x),y);
-
- return(0);
- }
-
- /************************************************************************
- *
-
- After being interpreted by the preprocessor, this program is replaced by code
- equivalent to the following:
-
- *
- ************************************************************************/
-
- #include <stdio.h>
-
- int main(void)
- {
- int x = 2;
- int y = 3;
-
- printf("value 1 = %d\n", ( (x) * (x) ) );
- printf("value 2 = %d\n", y);
-
- return(0);
- }
-
- /************************************************************************
- *
- This program produces the following output:
-
- value 1 = 4
- value 2 = 3
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 9.4. Scope of Macro Names (#undef) ΓòÉΓòÉΓòÉ
-
- A preprocessor undef directive causes the preprocessor to end the scope of a
- preprocessor definition.
-
- A preprocessor #undef directive has the form:
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇundefΓöÇΓöÇidentifierΓöÇΓöÇ><
-
- If the identifier is not currently defined as a macro, #undef is ignored
-
- You can also use the /U compiler option to undefine macros. The /U option does
- not undefine macros defined in source code.
-
- Examples of #undef Directives
-
- Related Information
-
- Macro Definition and Expansion (#define)
- Predefined Macro Names
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of #undef Directives ΓòÉΓòÉΓòÉ
-
- The following directives define BUFFER and SQR:
-
- #define BUFFER 512
- #define SQR(x) ((x) * (x))
-
- The following directives nullify these definitions:
-
- #undef BUFFER
- #undef SQR
-
- Any occurrences of the identifiers BUFFER and SQR that follow these #undef
- directives are not replaced with any replacement tokens. Once the definition of
- a macro has been removed by an #undef directive, the identifier can be used in
- a new #define directive.
-
-
- ΓòÉΓòÉΓòÉ 9.5. # Operator ΓòÉΓòÉΓòÉ
-
- The # (single number sign) operator converts a parameter of a function-like
- macro into a character string literal. For example, if macro ABC is defined
- using the following directive:
-
- #define ABC(x) #x
-
- all subsequent invocations of the macro ABC would be expanded into a character
- string literal containing the argument passed to ABC. For example:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé INVOCATION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "ABC(1)" Γöé "1" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "ABC(Hello there)" Γöé "Hello there" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The # operator should not be confused with the null directive.
-
- Use the # operator in a function-like macro definition according to the
- following rules:
-
- A parameter following # operator in a function-like macro is converted
- into a character string literal containing the argument passed to the
- macro.
-
- White-space characters that appear before or after the argument passed to
- the macro are deleted.
-
- Multiple white-space characters imbedded within the argument passed to
- the macro is replaced by a single space character.
-
- If the argument passed to the macro contains a string literal and if a \
- (backslash) character appears within the literal, a second \ character is
- inserted before the original \ when the macro is expanded.
-
- If the argument passed to the macro contains a " (double quotation mark)
- character, a \ character is inserted before the " when the macro is
- expanded.
-
- If the argument passed to the macro contains a ' (single quotation mark)
- character, a \ character is inserted before the ' when the macro is
- expanded.
-
- The conversion of an argument into a string literal occurs before macro
- expansion on that argument.
-
- If more than one ## operator or # operator appears in the replacement
- list of a macro definition, the order of evaluation of the operators is
- not defined.
-
- If the result of the macro expansion is not a valid character string
- literal, the behavior is undefined.
-
- See Function-Like Macros for more information about function-like macros.
-
- Examples of the # Operator
-
- Related Information
-
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
- Macro Concatenation with the ## and /**/ Operators
- Function-Like Macros
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of the # Operator ΓòÉΓòÉΓòÉ
-
- The following examples demonstrate the use of the # operator:
-
- #define STR(x) #x
- #define XSTR(x) STR(x)
- #define ONE 1
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé INVOCATION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "STR(\n "\n" '\n')" Γöé ""\n \"\\n\" '\\n'"" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "STR(ONE)" Γöé "ONE" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "XSTR(ONE)" Γöé "1" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "XSTR("hello")" Γöé "\"hello\"" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 9.6. Macro Concatenation with the ## and /**/ Operators ΓòÉΓòÉΓòÉ
-
- The ## (double number sign) operator concatenates two tokens in a macro
- invocation (text and/or arguments) given in a macro definition. In extended
- mode only, you can also use the /**/ (null comment) operator for macro
- concatenation.
-
- If a macro XY was defined using the following directive:
-
- #define XY(x,y) x##y
-
- the last token of the argument for x is concatenated with the first token of
- the argument for y.
-
- The following is an equivalent macro definition using /**/:
-
- #define XY(x, y) x/**/y
-
- Both definitions yield the same output:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé INVOCATION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "XY(1, 2)" Γöé "12" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "XY(Green, Γöé "Greenhouse" Γöé
- Γöé house)" Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Use the ## operator according to the following rules:
-
- The ## operator cannot be the very first or very last item in the
- replacement list of a macro definition.
-
- The last token of the item in front of the ## operator is concatenated
- with first token of the item following the ## operator.
-
- Concatenation takes place before any macros in arguments are expanded.
-
- If the result of a concatenation is a valid macro name, it is available
- for further replacement even if it appears in a context in which it would
- not normally be available.
-
- If more than one ## operator and/or # operator appears in the replacement
- list of a macro definition, the order of evaluation of the operators is
- not defined.
-
- Examples of the ## Operator
-
- Related Information
-
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
- # Operator
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of the ## Operator ΓòÉΓòÉΓòÉ
-
- The following examples demonstrate the use of the ## operator:
-
- #define ArgArg(x, y) x##y
- #define ArgText(x) x##TEXT
- #define TextArg(x) TEXT##x
- #define TextText TEXT##text
- #define Jitter 1
- #define bug 2
- #define Jitterbug 3
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé INVOCATION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "ArgArg(lady, bug)" Γöé ""ladybug"" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "ArgText(con)" Γöé ""conTEXT"" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "TextArg(book)" Γöé ""TEXTbook"" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "TextText" Γöé ""TEXTtext"" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "ArgArg(Jitter, Γöé "3" Γöé
- Γöé bug)" Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 9.6.1. /**/ Operator ΓòÉΓòÉΓòÉ
-
- The /**/ operator differs from the ## operator only in the way that the
- preprocessor treats white space between the operator and its arguments.
-
- For example, the macro definition:
-
- #define XY(x, y) x /**/y
-
- does not give the same result as:
-
- #define XY(x, y) x ##y
-
- because the preprocessor preserves white space with the /**/ operator. With the
- ## operator, arguments are concatenated without white space. For example, the
- invocation:
-
- XY(Turtle, neck)
-
- gives the following results:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé DEFINITION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "#define XY(x, y) x /**/y" Γöé "Turtle neck" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "#define XY(x, y) x/*stew*/y" Γöé "Turtle neck" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "#define XY(x, y) x ##y" Γöé "Turtleneck" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "#define XY(x, y) x##y" Γöé "Turtleneck" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- For /**/ to function the same way as ## in ANSI/ISO C, there can be no spaces
- between the operator and the arguments.
- Examples of the /**/ Operator
-
- The following examples demonstrate the use of the /**/ operator.
-
- #define lhk lighthousekeeper
- #define f(a,b) a/**/b
- #define g(a,b) a /**/b
- #define h(a,b) a/**/ b
- #define i(f) light/**/f
- #define a(f) f /**/housekeeper
- #define m l/**/hk
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé INVOCATION Γöé RESULT OF MACRO EXPANSION Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "f(l,hk)" Γöé "lighthousekeeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "g(light,housekeeper)Γöé "light housekeeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "g(lighthouse,keeper)Γöé "lighthouse keeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "h(lighthouse,keeper)Γöé "lighthouse keeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "f(light,house)" Γöé "lighthouse" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "i(housekeeper)" Γöé "lighthousekeeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "a(light)" Γöé "light housekeeper" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "m" Γöé "lighthousekeeper" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 9.7. Preprocessor Error Directive (#error) ΓòÉΓòÉΓòÉ
-
- A preprocessor error directive causes the preprocessor to generate an error
- message and causes the compilation to fail.
-
- The #error directive has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇerrorΓöÇΓöÇΓöÇΓöÇcharacterΓöÇΓö┤ΓöÇΓöÇ><
-
- Use the #error directive as a safety check during compilation. For example, if
- your program uses preprocessor conditional compilation directives, put #error
- directives in the source file to prevent code generation if a section of the
- program is reached that should be bypassed.
-
- For example, the directive
-
- #error Error in TESTPGM1 - This section should not be compiled
-
- generates the following error message:
-
- Error in TESTPGM1 - This section should not be compiled
-
- Related Information
-
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.8. File Inclusion (#include) ΓòÉΓòÉΓòÉ
-
- A preprocessor include directive causes the preprocessor to replace the
- directive with the contents of the specified file.
-
- A preprocessor #include directive has the form:
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇincludeΓöÇΓöÇΓö¼ΓöÇ"file_name"ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- Γö£ΓöÇΓöÉfile_name>ΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇΓöÉheader_name>ΓöÇΓöñ
- ΓööΓöÇidentifiersΓöÇΓöÇΓöÇΓöÿ
-
- The preprocessor resolves macros contained in a #include directive. After macro
- replacement, the resulting token sequence must consist of a file name enclosed
- in either double quotation marks or the characters < and >.
-
- For example:
-
- #define MONTH <july.h>
- #include MONTH
-
- If the file name is enclosed in double quotation marks, for example: #include
- "payroll.h" the preprocessor treats it as a user-defined file, and searches
- for the file in:
-
- 1. The directory where the original .c source file resides.
-
- 2. Any directories specified using the /I compiler option (that have not
- been removed by the /Xc option). Directories specified in the ICC
- environment variable are searched before those specified on the command
- line.
-
- 3. Any directories specified using the INCLUDE environment variable,
- provided the /Xi option is not in effect.
-
- If the file name is enclosed in angle brackets, for example: #include
- <stdio.h> it is treated as a system-defined file, and the preprocessor
- searches the following places in the order given:
-
- 1. Any directories specified using the /I compiler option (that have not
- been removed by the /Xc option). Directories specified in the ICC
- environment variable are searched before those specified on the command
- line.
-
- 2. Any directories specified using the INCLUDE environment variable,
- provided the /Xi option is not in effect.
-
- Note: If the file name is fully qualified, the preprocessor searches only the
- directory specified by the name.
-
- The new-line and > characters cannot appear in a file name delimited by < and
- >. The new-line and " (double quotation marks) character cannot appear in a
- file name delimited by " and ", although > can.
-
- Declarations that are used by several files can be placed in one file and
- included with #include in each file that uses them. For example, the following
- file defs.h contains several definitions and an inclusion of an additional
- file of declarations:
-
- /* defs.h */
- #define TRUE 1
- #define FALSE 0
- #define BUFFERSIZE 512
- #define MAX_ROW 66
- #define MAX_COLUMN 80
- int hour;
- int min;
- int sec;
- #include "mydefs.h"
-
- You can embed the definitions that appear in defs.h with the following
- directive:
-
- #include "defs.h"
-
- In the following example, a #define combines several preprocessor macros to
- define a macro that represents the name of the C standard I/O header file. A
- #include makes the header file available to the program.
-
- #define IO_HEADER <stdio.h>
- .
- .
- .
- #include IO_HEADER /* equivalent to specifying #include <stdio.h> */
- .
- .
- .
-
- Related Information
-
- Macro Definition and Expansion (#define)
- Preprocessor Directives
- Include Files
-
-
- ΓòÉΓòÉΓòÉ 9.9. Predefined Macro Names ΓòÉΓòÉΓòÉ
-
- VisualAge for C++ provides the following predefined macro names:
-
- ANSI/ISO Standard Predefined Macro Names
- VisualAge for C++ Predefined Macro Names
- Additional VisualAge for C++ Predefined Macros
- These predefined names cannot be subject to a #define or #undef preprocessor
- directive.
-
- Examples of Predefined Macros
-
- Related Information
-
- langlvl
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
-
-
- ΓòÉΓòÉΓòÉ 9.9.1. ANSI/ISO Standard Predefined Macro Names ΓòÉΓòÉΓòÉ
-
- Both C and C++ provide the following predefined macro names as specified in the
- ANSI/ISO C language standard:
-
- __DATE__
- A character string literal containing the date when the source file was
- compiled.
-
- The value of __DATE__ changes as the compiler processes any include files
- that are part of your source program. The date is in the form:
-
- "Mmm dd yyyy"
-
- where:
-
- Mmm Represents the month in an abbreviated form (Jan, Feb, Mar,
- Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, or Dec).
-
- dd Represents the day. If the day is less than 10, the first d
- is a blank character.
-
- yyyy Represents the year.
-
- The date is always set to the system date.
-
- __FILE__
- A character string literal containing the name of the source file.
-
- The value of __FILE__ changes as the compiler processes include files that
- are part of your source program. It can be set with the #line directive,
- described in Line Control (#line).
-
- __LINE__
- An integer representing the current source line number.
-
- The value of __LINE__ changes during compilation as the compiler processes
- subsequent lines of your source program. It can be set with the #line
- directive, described in Line Control (#line).
-
- __STDC__
- For C programs, the compiler sets this macro to the integer 1 (one) to
- indicate that the C compiler conforms to the ANSI/ISO standard. For C++
- programs, this macro is not defined, It has the integer value 0 when used
- in a #if statement, indicating that the C++ language is not a proper
- superset of C, and that the compiler does not conform to ANSI/ISO C.
-
- For more information on how C++ differs from ANSI/ISO C, see C and C++
- Compatibility.
-
- Note: This macro is not defined if the language level is set to anything
- other than ANSI.
-
- __TIME__
- A character string literal containing the time when the source file was
- compiled.
-
- The value of __TIME__ changes as the compiler processes any include files
- that are part of your source program. The time is in the form:
-
- "hh:mm:ss"
-
- where:
-
- hh Represents the hour.
-
- mm Represents the minutes.
-
- ss Represents the seconds.
-
- The time is always set to the system time.
-
- __cplusplus
- For C++ programs, this macro is set to the integer 1, indicating that the
- compiler is a C++ compiler. Note that this macro name has no trailing
- underscores.
-
-
- ΓòÉΓòÉΓòÉ 9.9.2. VisualAge for C++ Predefined Macro Names ΓòÉΓòÉΓòÉ
-
- VisualAge for C++ provides the following predefined macros. The value of all
- these macros is defined when the corresponding #pragma directive or compiler
- option is used. They cannot be the subject of a #define or #undef preprocessor
- directive. However, except for the __DATE__, __FUNCTION__, __LINE__, __TIME__,
- and __TIMESTAMP__ macros, they can be undefined on the command line using the
- /U option.
-
- __ANSI__
- Allows only language constructs that conform to ANSI/ISO C standard.
- Defined as 1 when using the #pragma langlvl directive or /Sa option.
-
- __EXTENDED__
- Allows additional language constructs provided by the VisualAge for C++
- implementation. Defined using the #pragma langlvl directive or /S2 option.
-
- __SAA__
- Allows only language constructs that conform to the most recent level of
- SAA C standards. Defined as 1 using the #pragma langlvl directive or /S2
- option. This macro is not defined for C++.
-
- __SAA_L2__
- Allows only language constructs that conform to SAA Level 2 C standards.
- Defined as 1 using the #pragma langlvldirective or /S2 option. This macro
- is not defined for C++.
-
- __COMPAT__
- Macro defined as 1 when the /Sc compiler option or the #pragma
- langlvl(compat) directive is specified for C++ language files. Indicates
- language constructs compatible with earlier versions of the C++ language
- are allowed. This macro is not defined for C.
-
- __FUNCTION__
- A character string containing the name of the function currently being
- compiled. For C++ programs, expands to the actual function prototype.
-
- _LONG_LONG
- Macro defined when the compiler is in a mode that permits long long int
- and unsigned long long int types.
-
- __LONGDOUBLE80
- Macro defined when the compiler is in a mode in which long double types
- have 80 bits of precision. This macro is always defined for VisualAge for
- C++. 80 bits of precision is the default for all language levels.
-
- __SOM_ENABLED__
- Macro defined when the SOM compiler options are used. Indicates that
- native SOM is supported. This option turns on implicit SOM mode, and also
- causes the file som.h to be included. SOM support for VisualAge for C++
- and the SOM options are described in the IBM VisualAge for C++ for Windows
- Programming Guide.
-
- __TEMPINC__
- Indicates the template-implementation file method of resolving template
- functions is being used. Defined as 1 using the /Ft compiler option.
-
- __TIMESTAMP__
- A character string literal containing the date and time when the source
- file was last modified.
-
- The value of __TIMESTAMP__ changes as the compiler processes any include
- files that are part of your source program. The date and time are in the
- form:
-
- "Day Mmm dd hh:mm:ss yyyy"
-
- where:
-
- Day Represents the day of the week (Mon, Tue, Wed, Thu, Fri,
- Sat, or Sun).
-
- Mmm Represents the month in an abbreviated form (Jan, Feb, Mar,
- Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, or Dec).
-
- dd Represents the day. If the day is less than 10, the first d
- is a blank character.
-
- hh Represents the hour.
-
- mm Represents the minutes.
-
- ss Represents the seconds.
-
- yyyy Represents the year.
-
- The date and time are always set to the system date and time.
-
-
- ΓòÉΓòÉΓòÉ 9.9.3. Additional VisualAge for C++ Predefined Macros ΓòÉΓòÉΓòÉ
-
- The macros identified in this section are provided to allow customers to write
- programs that use VisualAge for C++ services. Only those macros identified in
- this section should be used to request or receive VisualAge for C++ services.
-
- _CHAR_UNSIGNED
- Indicates default character type is unsigned. Defined when the #pragma
- chars(unsigned) directive is in effect, or when the /J+ compiler option is
- set.
-
- _CHAR_SIGNED
- Indicates default character type is signed. Defined when the #pragma
- chars(signed) directive is in effect, or when the /J- compiler option is
- set.
-
- __DBCS__
- Indicates DBCS support is enabled. Defined using the /Sn compiler option.
-
- __DDNAMES__
- Indicates ddnames are supported. Defined using the /Sh compiler option.
-
- __DEBUG_ALLOC__
- Maps memory management functions to their debug versions. Defined using
- the /Tm compiler option.
-
- __DLL__ and _DLL
- Indicates code for a DLL is being compiled. Defined using the /Ge-
- compiler option.
-
- _FP_INLINE_
- Inlines the trigonometric functions (cos, sin, and so on).
-
- __FUNCTION__
- Indicates the name of the function currently being compiled. For C++
- programs, expands to the actual function prototype.
-
- __HHW_INTEL__
- Indicates that the host hardware is an Intel** processor.
-
- __HOS_WIN__
- Indicates that the host operating system is Windows.
-
- __IBMC__
- Indicates the version number of the VisualAge C compiler.
-
- __IBMCPP__
- Indicates the version number of the VisualAge C++ compiler.
-
- __IMPORTLIB__
- Indicates that dynamic linking is used. Defined using the /Gd option.
-
- _M_I386
- Indicates code is being compiled for a 386 chip or higher.
-
- _M_IX86
- Indicates code is being compiled for a 386 chip or higher. Defined using
- the /qtune compiler options:
-
- /qtune=386 (equivalent to /G3)
- /qtune=486 (equivalent to /G4)
- /qtune=pentium (equivalent to /G5)
- /qtune=pentiumpro
- /qtune=blend
-
- __MULTI__ and _MT
- Indicates multithread code is being generated. Defined using the /Gm
- compiler option.
-
- __NO_DEFAULT_LIBS__
- Indicates that information about default libraries will not be included in
- object files. Defined using the /Gn option.
-
- __SOM_ENABLED__
- Indicates that native SOM is supported.
-
- __SPC__
- Indicates the subsystem libraries are being used. Defined using the /Rn
- compiler option.
-
- _STDCALL_SUPPORTED
- Indicates that the compiler supports __stdcall linkage.
-
- __THW_INTEL__
- Indicates that the target hardware is an Intel processor.
-
- __TOS_WIN__
- Indicates that the target operating system is Windows.
-
- __WINDOWS__
- Set to the integer 1. Indicates the product is a Windows compiler.
-
- _WIN32
- Indicates that the compiler generates Win32 code. Defined when the
- /qwin32s compiler option is set.
-
- __32BIT__
- Set to the integer 1. Indicates the product is a 32-bit compiler.
-
- The value of the __IBMC__ and __IBMCPP__ macros is 300. One of these two
- macros is always defined: when you compile C++ code, __IBMCPP__ is defined;
- when you compile C code, __IBMC__ is defined. The macros __WINDOWS__, _M_I386,
- and __32BIT__ are always defined also. The remaining macros, with the
- exception of __FUNCTION__, are defined when the corresponding #pragma
- directive or compiler option is used.
-
- Related Information
-
- #pragma chars.
- #pragma langlvl
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Predefined Macros ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- /**
- ** This example illustrates the __FUNCTION__ predefined macro
- ** in a C program.
- **/
- #include <stdio.h>
-
- int foo(int);
-
- main(int argc, char **argv) {
- int k = 1;
- printf (" In function %s \n",__FUNCTION__);
- foo(k);
- }
-
- int foo (int i) {
- printf (" In function %s \n",__FUNCTION__);
- }
-
- The output of this example is:
-
- In function main
- In function foo
-
- /**
- ** This example illustrates the __FUNCTION__ predefined macro
- ** in a C++ program.
- **/
- #include <stdio.h>
-
- int foo(int);
-
- main(int argc, char **argv) {
- int k = 1;
- printf (" In function %s \n",__FUNCTION__);
- foo(k);
- }
-
- int foo (int i) {
- printf (" In function %s \n",__FUNCTION__);
- }
-
- The output of this example is:
-
- In function main(int, char **)
- In function foo (int)
-
- /**
- ** This example illustrates the __FUNCTION__ predefined macro
- ** in a C++ program with virtual functions.
- **/
- #include <stdio.h>
- class X { public: virtual void func() = 0;};
-
- class Y : public X {
- public: void func() { printf("In function %s \n", __FUNCTION__);}
- };
-
- main() {
- Y aaa;
- aaa.func();
- }
-
- The output of this example is:
-
- In function Y::func()
-
-
- ΓòÉΓòÉΓòÉ 9.10. Conditional Compilation Directives ΓòÉΓòÉΓòÉ
-
- A preprocessor conditional compilation directive causes the preprocessor to
- conditionally suppress the compilation of portions of source code. These
- directives test a constant expression or an identifier to determine which
- tokens the preprocessor should pass on to the compiler and which tokens should
- be bypassed during preprocessing. The directives are:
-
- #if
- #ifdef
- #ifndef
- #else
- #elif
- #endif
-
- The preprocessor conditional compilation directive spans several lines:
-
- The condition specification line
- Lines containing code that the preprocessor passes on to the compiler if
- the condition evaluates to a nonzero value (optional)
- The #else line (optional)
- Lines containing code that the preprocessor passes on to the compiler if
- the condition evaluates to zero (optional)
- The preprocessor #endif directive
-
- For each #if, #ifdef, and #ifndef directive, there are zero or more #elif
- directives, zero or one #else directive, and one matching #endif directive.
- All the matching directives are considered to be at the same nesting level.
-
- You can nest conditional compilation directives. In the following directives,
- the first #else is matched with the #if directive.
-
- #ifdef MACNAME
- /* tokens added if MACNAME is defined */
- # if TEST <=10
- /* tokens added if MACNAME is defined and TEST <= 10 */
- # else
- /* tokens added if MACNAME is defined and TEST > 10 */
- # endif
- #else
- /* tokens added if MACNAME is not defined */
- #endif
-
- Each directive controls the block immediately following it. A block consists
- of all the tokens starting on the line following the directive and ending at
- the next conditional compilation directive at the same nesting level.
-
- Each directive is processed in the order in which it is encountered. If an
- expression evaluates to zero, the block following the directive is ignored.
-
- When a block following a preprocessor directive is to be ignored, the tokens
- are examined only to identify preprocessor directives within that block so
- that the conditional nesting level can be determined. All tokens other than
- the name of the directive are ignored.
-
- Only the first block whose expression is nonzero is processed. The remaining
- blocks at that nesting level are ignored. If none of the blocks at that
- nesting level has been processed and there is a #else directive, the block
- following the #else directive is processed. If none of the blocks at that
- nesting level has been processed and there is no #else directive, the entire
- nesting level is ignored.
-
- Examples of Conditional Compilation
-
- Related Information
-
- #if, #elif
- #ifdef
- #ifndef
- #else
- #endif
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.10.1. #if, #elif ΓòÉΓòÉΓòÉ
-
- The #if and #elif directives compare the value of the expression to zero.
-
- If the constant expression evaluates to a nonzero value, the tokens that
- immediately follow the condition are passed on to the compiler.
-
- If the expression evaluates to zero and the conditional compilation directive
- contains a preprocessor #elif directive, the source text located between the
- #elif and the next #elif or preprocessor #else directive is selected by the
- preprocessor to be passed on to the compiler. The #elif directive cannot appear
- after the preprocessor #else directive.
-
- All macros are expanded, any defined() expressions are processed and all
- remaining identifiers are replaced with the token 0.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇΓö¼ΓöÇifΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇconstant_expressionΓöÇΓöÇΓöÇΓöÇtoken_sequenceΓöÇΓö┤ΓöÇΓöÇ><
- ΓööΓöÇelifΓöÇΓöÿ
-
- The expressions that are tested must be integer constant expressions with the
- following properties:
-
- No casts are performed.
- Arithmetic is performed using long int values.
- The expression can contain defined macros. No other identifiers can
- appear in the expression.
- The constant expression can contain the unary operator defined. This
- operator can be used only with the preprocessor keyword #if. The
- following expressions evaluate to 1 if the identifier is defined in the
- preprocessor, otherwise to 0:
-
- defined identifier
- defined(identifier)
-
- For example:
-
- #if defined(TEST1) || defined(TEST2)
-
- Note: If a macro is not defined, a value of 0 (zero) is assigned to it. In
- the following example, TEST must be a macro identifier:
-
- #if TEST >= 1
- printf("i = %d\n", i);
- printf("array[i] = %d\n", array[i]);
- #elif TEST < 0
- printf("array subscript out of bounds \n");
- #endif
-
- Example of #if and #elif Directives
-
- Related Information
-
- Conditional Compilation Directives
- #ifdef
- #ifndef
- #endif
- Preprocessor Directives
- if
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of #if and #elif Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example uses the #if and #elif directives to assign values to an
- array.
-
- *
- ************************************************************************/
-
- #include <stdio.h>
-
- int main(void)
- {
- int i;
- char *arrayname = "realarray";
- int realarray[] = { 1, 2, 3 };
- int array1[] = { 4, 5, 6 };
- int array2[] = { 7, 8, 9 };
-
- #if ( (defined(LEVEL1)) && (TEST > 1) )
- for (i = 0; i < 3; i++)
- realarray[i] = array1[i];
- arrayname = "array1";
- #elif (defined(LEVEL2))
- for (i = 0; i < 3; i++)
- realarray[i] = array2[i];
- arrayname = "array2";
- #endif
-
- printf("realarray[] now has the contents of %s[]\n", arrayname);
-
- /* Assuming only LEVEL2 is defined, the expected output is:
-
- realarray[] now has the contents of array2[] */
-
- }
-
-
- ΓòÉΓòÉΓòÉ 9.10.2. #ifdef ΓòÉΓòÉΓòÉ
-
- The #ifdef directive checks for the existence of macro definitions.
-
- If the identifier specified is defined as a macro, the tokens that immediately
- follow the condition are passed on to the compiler.
-
- The preprocessor #ifdef directive has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇifdefΓöÇΓöÇidentifierΓöÇΓöÇΓöÇΓöÇtoken_sequenceΓöÇΓö┤ΓöÇΓöÇ><
-
- The following example defines MAX_LEN to be 75 if EXTENDED is defined for the
- preprocessor. Otherwise, MAX_LEN is defined to be 50.
-
- #ifdef EXTENDED
- # define MAX_LEN 75
- #else
- # define MAX_LEN 50
- #endif
-
- Related Information
-
- Conditional Compilation Directives
- #ifndef
- #if, #elif
- #else
- #endif
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.10.3. #ifndef ΓòÉΓòÉΓòÉ
-
- The #ifndef directive checks for the existence of macro definitions.
-
- If the identifier specified is not defined as a macro, the tokens that
- immediately follow the condition are passed on to the compiler.
-
- The preprocessor #ifndef directive has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇifndefΓöÇΓöÇidentifierΓöÇΓöÇΓöÇΓöÇtoken_sequenceΓöÇΓö┤ΓöÇΓöÇ><
-
- An identifier must follow the #ifndef keyword. The following example defines
- MAX_LEN to be 50 if EXTENDED is not defined for the preprocessor. Otherwise,
- MAX_LEN is defined to be 75.
-
- #ifndef EXTENDED
- # define MAX_LEN 50
- #else
- # define MAX_LEN 75
- #endif
-
- Related Information
-
- Conditional Compilation Directives
- #ifdef
- #if, #elif
- #else
- #endif
- Macro Definition and Expansion (#define)
- Scope of Macro Names (#undef)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.10.4. #else ΓòÉΓòÉΓòÉ
-
- If the condition specified in the #if, #ifdef, or #ifndef directive evaluates
- to 0, and the conditional compilation directive contains a preprocessor #else
- directive, the source text located between the preprocessor #else directive and
- the preprocessor #endif directive is selected by the preprocessor to be passed
- on to the compiler.
-
- The preprocessor #else directive has the form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇelseΓöÇΓöÇΓöÇΓöÇtoken_sequenceΓöÇΓö┤ΓöÇΓöÇ><
-
- The following example defines MAX_LEN to be 50 if EXTENDED is not defined for
- the preprocessor. Otherwise, MAX_LEN is defined to be 75.
-
- #ifndef EXTENDED
- # define MAX_LEN 50
- #else
- # define MAX_LEN 75
- #endif
-
- Related Information
-
- Conditional Compilation Directives
- #if, #elif
- #ifdef
- #ifndef
- #endif
- Macro Definition and Expansion (#define)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.10.5. #endif ΓòÉΓòÉΓòÉ
-
- The preprocessor #endif directive ends the conditional compilation directive.
-
- It has the form:
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇendifΓöÇΓöÇ><
-
- The following example shows preprocessor conditional compilation directives
- ended by the #endif directive.
-
- #if defined(LEVEL1)
- # define SIZEOF_INT 16
- # ifdef PHASE2
- # define MAX_PHASE 2
- # else
- # define MAX_PHASE 8
- # endif
- #elif defined(LEVEL2)
- # define SIZEOF_INT 32
- # define MAX_PHASE 16
- #endif
-
- Related Information
-
- Conditional Compilation Directives
- #if, #elif
- #ifdef
- #ifndef
- #else
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Conditional Compilation Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows how you can nest preprocessor conditional
- compilation directives:
-
- #if defined(TARGET1)
- # define SIZEOF_INT 16
- # ifdef PHASE2
- # define MAX_PHASE 2
- # else
- # define MAX_PHASE 8
- # endif
- #elif defined(TARGET2)
- # define SIZEOF_INT 32
- # define MAX_PHASE 16
- #else
- # define SIZEOF_INT 32
- # define MAX_PHASE 32
- #endif
-
- The following program contains preprocessor conditional compilation directives:
-
- *
- ************************************************************************/
-
- /**
- ** This example contains preprocessor
- ** conditional compilation directives.
- **/
-
- #include <stdio.h>
-
- int main(void)
- {
- static int array[ ] = { 1, 2, 3, 4, 5 };
- int i;
-
- for (i = 0; i <= 4; i++)
- {
- array[i] *= 2;
-
- #if TEST >= 1
- printf("i = %d\n", i);
- printf("array[i] = %d\n", array[i]);
- #endif
-
- }
- return(0);
- }
-
-
- ΓòÉΓòÉΓòÉ 9.11. Line Control (#line) ΓòÉΓòÉΓòÉ
-
- A preprocessor line control directive supplies line numbers for compiler
- messages. It causes the compiler to view the line number of the next source
- line as the specified number.
-
- A preprocessor #line directive has the form:
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇdecimal_constantΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇlineΓöÇΓöÿ Γöé ΓööΓöÇ"file_name"ΓöÇΓöÿ Γöé
- ΓööΓöÇcharactersΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- In order for the compiler to produce meaningful references to line numbers in
- preprocessed source, the preprocessor inserts #line directives where necessary
- (for example, at the beginning and after the end of included text).
-
- A file name specification enclosed in double quotation marks can follow the
- line number. If you specify a file name, the compiler views the next line as
- part of the specified file. If you do not specify a file name, the compiler
- views the next line as part of the current source file.
-
- The token sequence on a #line directive is subject to macro replacement. After
- macro replacement, the resulting character sequence must consist of a decimal
- constant, optionally followed by a file name enclosed in double quotation
- marks.
-
- You can use #line control directives to make the compiler provide more
- meaningful error messages.
-
- Example of #line Directives
-
- Related Information
-
- Preprocessor Directives
- Decimal Constants
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of #line Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following program uses #line control directives to give each function an
- easily recognizable line number:
-
- *
- ************************************************************************/
-
- /**
- ** This example illustrates #line directives.
- **/
-
- #include <stdio.h>
- #define LINE200 200
-
- int main(void)
- {
- func_1();
- func_2();
- }
-
- #line 100
- func_1()
- {
- printf("Func_1 - the current line number is %d\n",__LINE__);
- }
-
- #line LINE200
- func_2()
- {
- printf("Func_2 - the current line number is %d\n",__LINE__);
- }
-
- /************************************************************************
- *
-
- This program produces the following output:
-
- Func_1 - the current line number is 102
- Func_2 - the current line number is 202
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 9.12. Null Directive (#) ΓòÉΓòÉΓòÉ
-
- The null directive performs no action. It consists of a single # on a line of
- its own.
-
- The null directive should not be confused with the # operator or the character
- that starts a preprocessor directive.
-
- In the following example, if MINVAL is a defined macro name, no action is
- performed. If MINVAL is not a defined identifier, it is defined 1.
-
- #ifdef MINVAL
- #
- #else
- #define MINVAL 1
- #endif
-
- Related Information
-
- Preprocessor Directives
- Null Statement
-
-
- ΓòÉΓòÉΓòÉ 9.13. Pragma Directives (#pragma) ΓòÉΓòÉΓòÉ
-
- A pragma is an implementation-defined instruction to the compiler. It has the
- general form:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇΓöÇΓöÇcharacter_sequenceΓöÇΓö┤ΓöÇΓöÇ><
-
- where character_sequence is a series of characters giving a specific compiler
- instruction and arguments, if any.
-
- The character_sequence on a pragma is subject to macro substitutions. For
- example,
-
- #define XX_ISO_DATA isolated_call(LG_ISO_DATA)
- // ...
- #pragma XX_ISO_DATA
-
- More than one pragma construct can be specified on a single #pragma directive.
- The compiler ignores unrecognized pragmas.
-
- The VisualAge for C++ compiler recognizes the following pragmas:
-
- alloc_text Groups functions into separate 32-bit code sections.
-
- chars Sets the sign type of character data.
-
- comment Places a comment into the object file.
-
- data_seg Places static and external variables in different 32-bit
- data sections.
-
- define Forces the definition of a template class without actually
- defining an object of the class. This directive is valid for
- C++ programs only.
-
- disjoint Lists the identifiers that are not aliased to each other
- within the scope of their use.
-
- entry Specifies the function to be used as the entry point for the
- application being built.
-
- export Declares that a DLL function is to be exported and specifies
- the name of the function outside the DLL.
-
- handler Registers an exception handler for a function.
-
- hdrfile Specifies the filename of the precompiled header to be
- generated and/or used.
-
- hdrstop Manually terminates the initial sequence of #include
- directives being considered for precompilation.
-
- implementation Tells the compiler the name of the file that contains the
- function template definitions corresponding to the template
- declarations in the include file containing the pragma. This
- directive is valid for C++ programs only.
-
- info Controls the diagnostic messages generated by the /Wgroup
- compiler options.
-
- isolated_call Lists functions that do not alter data objects visible at
- the time of the function call.
-
- langlvl Selects the C or C++ language level for compilation.
-
- library Instructs the linker to pull in the appropriate libraries at
- link time.
-
- linkage Identifies the linkage or calling convention used on a
- function call. This directive is valid for C programs only.
-
- map Tells the compiler that all references to an identifier are
- to be converted to a new name.
-
- margins Specifies the columns in the input line that are to be
- scanned for input to the compiler. This directive is valid
- for C programs only.
-
- pack Specifies the alignment rules to use for the structures,
- unions, and classes that follow it.
-
- page Skips pages of the generated source listing.
-
- pagesize Sets the number of lines per page for the generated source
- listing.
-
- priority Specifies the order in which static objects are to be
- initialized at run time. This directive is valid for C++
- programs only.
-
- sequence Defines the section of the input line that is to contain
- sequence numbers.
-
- skip Skips lines of the generated source listing.
-
- sourcedir Defines a new path to the directory containing the original
- source of an include file. This directive is valid for C++
- programs only.
-
- strings Sets storage type for strings.
-
- subtitle Places text on generated source listings.
-
- title Places text on generated source listings.
-
- undeclared Used by the compiler to mark template functions that were
- called but never declared. This directive is valid for C++
- programs only.
-
- weak Adds an alternate function name with weak binding for the
- specified function.
-
- The following #pragma directives must appear before any statements in the C
- source code:
-
- chars
- langlvl
- strings
-
- The other #pragma directives can be used throughout your program to affect a
- selected block of source code.
-
- The following VisualAge for C++ for OS/2 pragmas are not supported by IBM
- VisualAge for C++ for Windows:
-
- checkout
- import
- stack16
- seg16
- linkage with the following subspecifiers:
- - far16 cdecl
- - far16 fastcall
- - far16 pascal
- - pascal
-
- A warning is issued if any of these pragmas are used.
-
- The following Microsoft Visual C++ #pragma directives are not supported by
- VisualAge for C++:
-
- function
- intrinsic
- inline_depth
- warning
-
- Related Information
-
- Restrictions on #pragma Directives
- Preprocessor Directives
-
- VisualAge for C++ also provides several pragmas to support the IBM System
- Object Model (SOM), which provides a common programming interface for building
- and using software objects.
-
- SOM support for VisualAge for C++ and the SOM pragmas are described in the IBM
- VisualAge for C++ for Windows User's Guide.
-
-
- ΓòÉΓòÉΓòÉ 9.13.1. Restrictions on #pragma Directives ΓòÉΓòÉΓòÉ
-
- Some #pragma directives must appear in a certain place in your source, or can
- appear a limited number of times. The following table lists the restrictions
- for #pragma directives.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé #PRAGMA Γöé RESTRICTION OF PLACE- Γöé RESTRICTION ON NUMBER OF OCCURRENCES Γöé
- Γöé Γöé MENT Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "chars" Γöé On the first #PRAGMA Γöé Once Γöé
- Γöé Γöé directive, and before Γöé Γöé
- Γöé Γöé any code or directive Γöé Γöé
- Γöé Γöé (except "#line") Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "comment"Γöé "copyright" directive Γöé "compiler" and "timestamp" directives Γöé
- Γöé Γöé must appear before any Γöé can appear only once Γöé
- Γöé Γöé code Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "entry" Γöé No restriction Γöé One per ".exe" or ".dll" If there is Γöé
- Γöé Γöé Γöé more than one, the result is undefined. Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "langlvl"Γöé On the first #PRAGMA Γöé Once Γöé
- Γöé Γöé directive, and before Γöé Γöé
- Γöé Γöé any code or directive Γöé Γöé
- Γöé Γöé (except "#line") Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "linkage"Γöé Before any declaration Γöé Once for each function Γöé
- Γöé Γöé of or call to the Γöé Γöé
- Γöé Γöé function Γöé Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé "strings"Γöé Before any code Γöé Once Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 9.13.2. alloc_text ΓòÉΓòÉΓòÉ
-
- The #pragma alloc_text directive lets you group functions into different 32-bit
- code sections.
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇalloc_textΓöÇΓöÇ(ΓöÇΓöÇcode_sectionΓöÇΓöÇΓöÇΓöÇ,ΓöÇΓöÇfunctionΓöÇΓö┤ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The code_section is the name of the code segment where you want to place
- function. You can specify any number of functions to be included in the named
- code_section.
-
- Functions that are not grouped in a code section by #pragma alloc_text are
- placed in the default 32-bit code section CODE32, or whatever was specified on
- the /NT option. You can also use #pragma alloc_text to explicitly place
- functions in CODE32 by specifying it as the code_section.
-
- Defining your own code sections allows you to organize functions in memory so
- that the working set requires fewer pages of memory. You can also specify
- attributes for each section, such as execute-only or preload. Code section
- attributes are specified with the /SECTION and /CODE linker options.
-
- For example, the following creates two code sections, one load on call, the
- other preload:
-
- #pragma alloc_text(pl_seg, func1)
- #pragma alloc_text(loc_seg, func2)
-
- For more information on linker attributes and .DEF files, see the IBM VisualAge
- for C++ for Windows User's Guide.
-
- Related Information
-
- data_seg
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.3. chars ΓòÉΓòÉΓòÉ
-
- The #pragma chars directive specifies that the compiler is to treat all char
- objects as signed or unsigned.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇcharsΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇunsignedΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇsignedΓöÇΓöÇΓöÇΓöÿ
-
- This pragma must appear before any statements in a file. Once specified, it
- applies to the rest of the file and cannot be turned off. If a source file
- contains any functions that you want to be compiled without #pragma chars,
- place these functions in a different file.
-
- The default character type behaves like an unsigned char.
-
- Related Information
-
- Characters
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.4. comment ΓòÉΓòÉΓòÉ
-
- The #pragma comment directive places a comment into the object file.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇcommentΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇcompilerΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γö£ΓöÇdateΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇtimestampΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇΓö¼ΓöÇcopyrightΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöñ
- Γöé ΓööΓöÇuserΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ ΓööΓöÇ,"token_sequence"ΓöÇΓöÿ Γöé
- ΓööΓöÇlibΓöÇΓöÇ,"<path_name>"ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The comment type can be:
-
- compiler The name and version of the compiler are appended to the end of
- the generated object module.
-
- date The date and time of compilation are appended to the end of the
- generated object module.
-
- timestamp The date and time of the last modification of the source is
- appended to the end of the generated object module.
-
- copyright The text specified by the token_sequence is placed by the
- compiler into the generated object module and is loaded into
- memory when the program is run.
-
- user The text specified by the token_sequence is placed by the
- compiler into the generated object but is not loaded into
- memory when the program is run.
-
- lib A library search record is place into the generated object
- module. Equivalent to #pragma library.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.5. data_seg ΓòÉΓòÉΓòÉ
-
- The #pragma data_seg directive lets you place static and external variables in
- different 32-bit data segments.
-
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇdata_segΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γö£ΓöÇdata_segmentΓöÇΓöÇΓöÇΓöñ ΓööΓöÇ,ΓöÇΓöÇclassΓöÇΓöÿ
- ΓööΓöÇ"data_segment"ΓöÇΓöÿ
-
- All static and external variables defined after the #pragma data_seg directive
- are placed in the named data_segment. The pragma is in effect until the next
- #pragma data_seg directive or the end of the compilation unit.
-
- Quotation marks around data_segment are optional and provided for compatibility
- with Microsoft Visual C++.
-
- Writable string literals used to initialize pointers are not placed in the
- named data_segment, but in the default 32-bit data segment (DATA32). To place a
- string in a particular data segment, use an array to initialize the string
- instead of a pointer. For example:
-
- char a[ ] = "mystring";
- instead of
-
- char *a = "mystring";
-
- Static and external variables defined before the first #pragma data_seg
- directive are placed in the default DATA32 segment, with the exception of
- uninitialized variables and variables explicitly initialized to zero, which are
- placed in the BSS32 segment. You can also use #pragma data_seg to explicitly
- place variables in the DATA32 segment by specifying no data_segment, for
- example, #pragma data_seg(). However, you cannot use the CONST32_RO or BSS32
- segments in a #pragma data_seg directive.
-
- Note: Because the variables in the BSS32 data segment are initialized at load
- time and loaded separately from the rest of your program, they take less space
- in your executable file. If you place these variables in a different data
- segment, this optimization does not take place, and the size of your executable
- module increases. For this reason, if the size of your executable file is
- critical to you, you should define all variables initialized to zero (either
- explicitly or by default) before the first occurrence of #pragma data_seg.
-
- Defining your own data segments allows you to group data depending on how it is
- used and to specify different attributes for different groups of data, such as
- when the data should be loaded. Data section attributes are specified with the
- /SECTION and /DATA linker options. These are described in the IBM VisualAge for
- C++ for Windows User's Guide.
-
- For example, when you build a DLL, you might have one set of data that you want
- to make global for all processes that use the DLL, and a different set of data
- that you want to copy for each process. You could use #pragma data_seg to place
- the data in two different segments as follows:
-
- #pragma data_seg(globdata)
-
- static int counter1 = 0;
- static int counter2 = 0;
- .
- .
- .
- #pragma data_seg(instdata)
-
- static int instcount1 = 0;
- static int instcount2 = 0;
- .
- .
- .
-
- Related Information
-
- alloc_text
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.6. define ΓòÉΓòÉΓòÉ
-
- The #pragma define directive forces the definition of a template class without
- actually defining an object of the class.
-
- C++ Note: This directive is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇdefineΓöÇΓöÇ(ΓöÇΓöÇtemplate_class_nameΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The pragma can appear anywhere that a declaration is allowed. It is used when
- organizing your program for the efficient or automatic generation of template
- functions. "Using Templates in C++ Programs" in the IBM VisualAge for C++ for
- Windows Programming Guide gives more information about using #pragma define.
-
- Related Information
-
- C++ Templates
- Pragma Directives (#pragma)
- Preprocessor Directives
- "Using Templates in C++ Programs" in the IBM VisualAge for C++ for
- Windows Programming Guide
-
-
- ΓòÉΓòÉΓòÉ 9.13.7. disjoint ΓòÉΓòÉΓòÉ
-
- The #pragma disjoint directive lists the identifiers that are not aliased to
- each other within the scope of their use. This directive is valid for C
- programs only.
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇdisjointΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇ*ΓöÇΓöÿ ΓööΓöÇidentifierΓöÇΓöÿ
-
- where identifier is a primary expression that can be the name of an operator
- function, conversion function, destructor, or a qualified name.
-
- The directive informs the compiler that none of the identifiers listed shares
- the same physical storage, which provides more opportunity for optimizations.
- If any identifiers actually share physical storage, the pragma may give
- incorrect results.
-
- The pragma can appear anywhere in the source program that a declaration is
- allowed. An identifier in the directive must be visible at the point in the
- program where the pragma appears. The identifiers in the disjoint name list
- cannot refer to any of the following:
-
- A member of a structure, or union
- A structure, union, or enumeration tag
- An enumeration constant
- A typedef name
- A label
-
- The identifiers must be declared before they are used in the pragma. A pointer
- in the identifier list must not have been dereferenced or used as a function
- argument before appearing in the directive.
-
- The following example shows the use of #pragma disjoint.
-
- int a, b, *ptr_a, ptr_b;
- #pragma disjoint(*ptr_a, b) // *ptr_a never points to b
- #pragma disjoint(*ptr_b, a) // *ptr_b never points to a
- one_function()
- {
- b = 6;
- *ptr_a = 7; // Assignment will not change the value of b
- another_function(b); // Argument "b" has the value 6
- }
-
- Because external pointer ptr_a does not share storage with and never points to
- the external variable b, the assignment of 7 to the object that ptr_a points
- to will not change the value of b. Likewise, external pointer ptr_b does not
- share storage with and never points to the external variable a. The compiler
- can assume that the argument to another_function has the value 6 and will not
- reload the variable from memory.
-
- The ignprag compiler option causes aliasing pragmas to be ignored. Use this
- option to debug applications containing the #pragma disjoint directive.
- Compiler options are described in the IBM VisualAge for C++ for Windows User's
- Guide.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.8. entry ΓòÉΓòÉΓòÉ
-
- The #pragma entry directive specifies the function to be used as the entry
- point for the application being built.
-
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇentryΓöÇΓöÇ(ΓöÇΓöÇfunction_nameΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The function_name function must be in the same compilation unit as the #pragma
- entry directive, and must be a defined external function.
-
- Normally when an application is started, the Windows system calls the C library
- entry point. When you specify a different entry point using #pragma entry, the
- system calls that entry point and does not perform any C library initialization
- or termination. If you use #pragma entry, you must ensure that your executable
- file does not require library initialization or termination, or you must
- provide your own initialization and termination functions.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.9. export ΓòÉΓòÉΓòÉ
-
- The #pragma export directive declares that a DLL function or variable is to be
- exported and specifies the name of the function or variable outside the DLL.
- #pragma export
-
- >>ΓöÇΓöÇ#-pragma-exportΓöÇΓöÇ(ΓöÇΓöÇidentifierΓöÇΓöÇ,ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ,ΓöÇΓöÇordinalΓöÇΓöÇΓöÇΓöÇΓöÇ>
- ΓööΓöÇ"ΓöÇΓöÇexport_nameΓöÇΓöÇ"ΓöÇΓöÿ
- >ΓöÇΓöÇ)ΓöÇΓöÇ><
- NOTE:
- (1) The ordinal is optional in C++
-
- The identifier is the name of the function or variable in the DLL. The
- export_name is the name for identifier outside of the DLL. If no export_name is
- specified, identifier is used.
-
- The export_name must be fully decorated according to the linkage convention
- that applies to it.
-
- The ordinal is the number of the identifier within the DLL. Import by ordinal
- number is only permitted using the Win32 API GetProcAddress. Refer to the Win32
- documentation for more information. Ordinal numbers for exports are described
- in more detail in the IBM VisualAge for C++ for Windows Programming Guide.
-
- For example, the statements:
-
- int deborah(int);
- #pragma export(deborah, "?catherine", 4)
-
- declare that the function deborah is to be exported, and can be imported by
- another module using the name ?catherine or the ordinal number 4. Note that
- ?catherine is decorated according to the default linkage convention, _Optlink.
- See #pragma import for information on importing functions and variables.
-
- You can also use the _Export keyword to export a function. If you use the
- keyword, you cannot specify a different name or an ordinal for the exported
- function.
-
- If you use #pragma export to export your function, you may still need to
- provide an EXPORTS entry for that function in your module definition (.DEF)
- file. If your function has any of the following default characteristics
-
- Has shared data
- Has no I/O privileges
- Is not resident
-
- it does not require an EXPORTS entry. If your function has characteristics
- other than the defaults, the only way you can specify them is with an EXPORTS
- entry in your .DEF file.
-
- Note: To create an import library for the DLL, and you are not passing
- objects to ILIB, you must provide a .DEF file with an EXPORTS entry for every
- function. You can create the .DEF file from the DLL itself. The description of
- ILIB in the IBM VisualAge for C++ for Windows User's Guide describes how to do
- this.
-
- No .DEF file is needed if you use _Export on all exports and the object files
- are passed to the ILIB program.
-
- For more information on DLLs and .DEF files, see the IBM VisualAge for C++ for
- Windows Programming Guide.
-
- Related Information
-
- #pragma import
- _Export Keyword
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.10. handler ΓòÉΓòÉΓòÉ
-
- The #pragma handler directive registers an exception handler for a function.
-
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇhandlerΓöÇΓöÇ(ΓöÇΓöÇfunctionΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The function is the name of the function for which the exception handler is to
- be registered. You should declare it before you use it in this directive.
-
- The #pragma handler directive generates the code at compile time to install the
- VisualAge for C++ exception handler _Exception before starting execution of the
- function. It also generates code to remove the exception handler at function
- exit.
-
- You must use this directive whenever you change library environments or enter a
- user-created DLL.
-
- Note: If you are using the subsystem libraries, the _Exception function is not
- provided. To use the #pragma handler directive in a subsystem, you must provide
- your own exception handler named _Exception. Your exception hander must have
- __cdecl linkage.
-
- For more information on exception handling and _Exception, see the IBM
- VisualAge for C++ for Windows Programming Guide.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.11. hdrfile ΓòÉΓòÉΓòÉ
-
- The #pragma hdrfile directive specifies the file name of the precompiled header
- to be generated and/or used.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇhdrfileΓöÇΓöÇ"file_name"ΓöÇΓöÇ><
-
- It must appear before the first #include directive and either the /Fi option or
- the /Si option is specified. The /Si and /Fi options allow more than one
- precompiled header to be use for a single application.
-
- If a file name is specified both on the command line and on #pragma hdrfile,
- the name specified on the pragma takes precedence. If the name specified is a
- directory, the compiler searches for or generates a file with the default name
- in that directory.
-
- In order to maximize the reuse of precompiled headers, the use #pragma hdrfile
- in combination with #pragma hdrstop to manually limit the initial sequence of
- #include directives.
-
- Use precompiled header files to decrease compile time. Using precompiled
- headers will not improve compile time performance in most applications without
- some organization of the headers included by each source file.
-
- The IBM VisualAge for C++ for Windows Programming Guide describes how to
- structure your files so the compiler can take full advantage of the precompiled
- headers.
-
- Examples of #pragma hdrfile Directives
-
- Related Information
-
- Precompiled header files
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of #pragma hdrfile Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, the headers h1.h and h2.h are precompiled using the
- file fred.pch (provided /Si or /Fi are specified). If /Fidave.pch is specified
- alone, the compiler looks for the precompiled headers in fred.pch but will not
- generate new headers.
-
- *
- ************************************************************************/
-
- #pragma hdrfile "fred.pch"
- #include "h1.h"
- #include "h2.h"
- main () {}
-
- /************************************************************************
- *
-
- In the following example, only the header h1.h will be precompiled using the
- file fred.pch (provided /Si or /Fi are specified). If /Sidave.pch is specified
- alone, the compiler looks for the precompiled headers in fred.pch but will not
- generate new headers.
-
- *
- ************************************************************************/
-
- #pragma hdrfile "fred.pch"
- #include "h1.h"
- #pragma hdrstop
- #include "h2.h"
- main () {}
-
-
- ΓòÉΓòÉΓòÉ 9.13.12. hdrstop ΓòÉΓòÉΓòÉ
-
- The #pragma hdrstop directive manually terminates the initial sequence of
- #include directives being considered for precompilation.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇhdrstopΓöÇΓöÇ><
-
- It has no effect if:
-
- The initial sequence of #include directives has already ended
- Neither the /Fi option nor the /Si option is specified
- It does not appear in the primary source file
-
- Use precompiled header files to decrease compile time. Using precompiled
- headers will not improve compile time performance in most applications without
- some organization of the headers included by each source file.
-
- The IBM VisualAge for C++ for Windows User's Guide describes how to structure
- your files so the compiler can take full advantage of the precompiled headers.
-
- Examples of #pragma hdrstop Directives
-
- Related Information
-
- Precompiled header files
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of #pragma hdrstop Directives ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, only the header h1.h will be precompiled using the
- file default.pch (provided /Si or /Fi are specified). If /Sidave.pch
- /Fijohn.pch are specified, the compiler will look for the precompiled headers
- in john.pch and will regenerate them if they are not found or not usable.
-
- *
- ************************************************************************/
-
- #include "h1.h"
- #pragma hdrstop
- #include "h2.h"
- main () {}
-
- /************************************************************************
- *
-
- In the following example, no precompiled headers will be generated or used for
- the compilation, even if /Fi or /Si are specified.
-
- *
- ************************************************************************/
-
- #pragma hdrstop
- #include "h1.h"
- #include "h2.h"
- main () {}
-
-
- ΓòÉΓòÉΓòÉ 9.13.13. implementation ΓòÉΓòÉΓòÉ
-
- The #pragma implementation directive tells the compiler the name of the file
- containing the function-template definitions that correspond to the template
- declarations in the include file which contains the pragma.
-
- C++ Note: This directive is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇimplementationΓöÇΓöÇ(ΓöÇΓöÇstring_literalΓöÇΓöÇ)ΓöÇΓöÇ><
-
- This pragma can appear anywhere that a declaration is allowed. It is used when
- organizing your program for the efficient or automatic generation of template
- functions. "Using Templates in C++ Programs" in the IBM VisualAge for C++ for
- Windows Programming Guide gives more information about using #pragma
- implementation.
-
- Related Information
-
- C++ Templates
- Pragma Directives (#pragma)
- Preprocessor Directives
- "Using Templates in C++ Programs" in the IBM VisualAge for C++ for
- Windows Programming Guide
-
-
- ΓòÉΓòÉΓòÉ 9.13.14. import ΓòÉΓòÉΓòÉ
-
- Note: The #pragma import directive is not supported in IBM VisualAge for C++
- for Windows. The compiler accepts the directive, but issues a warning to use
- the _Import keyword or the __declspec(dllimport) keyword instead.
-
- The VisualAge for C++ linker does not recognize #pragma import; you must supply
- an import library.
-
- For more information on DLLs and importing functions see the IBM VisualAge for
- C++ for Windows Programming Guide.
-
- Related Information
-
- export
- _Export Keyword
- _Import Keyword
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.15. info ΓòÉΓòÉΓòÉ
-
- The #pragma info directive controls the diagnostic messages generated by the
- /Wgroup compiler options.
-
- C++ Note: This directive is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇinfoΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇallΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γö£ΓöÇnoneΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇrestoreΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓö¼ΓöÇgroupΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÿ
- ΓööΓöÇnogroupΓöÇΓöÿ
-
- The #pragma info directive replaces the #pragma checkout directive for
- controlling diagnostics. Specifying #pragma info(group) causes all messages
- associated with that diagnostic group to be generated. Specifying #pragma
- info(nogroup) suppresses all messages associated with that group.
-
- For example, to generate messages for missing function prototypes and
- statements with no effect, but not for uninitialized variables, specify:
-
- #pragma info(pro, eff, nouni)
-
- The #pragma directive overrides any /Wgroup options stated on the command line.
-
- Use #pragma info(all) to turn on all diagnostic checking. Use #pragma
- info(none) to turn off all diagnostic suboptions for specific portions of your
- program. Specifying #pragma info(restore) restores the options that were in
- effect before the previous #pragma info directive.
-
- Because #pragma info operates like a stack, the options restored may not be
- those given on the command line. If no options were previously in effect,
- #pragma info(restore) does nothing.
-
- The following list explains the groups of diagnostic messages controlled by
- each group option:
-
- Group Diagnostics
- cmp Possible redundancies in unsigned comparisons.
- cnd Possible redundancies or problems in conditional expressions.
- cns Operations involving constants.
- cnv Conversions.
- dcl Consistency of declarations.
- eff Statements with no effect.
- enu Consistency of enum variables.
- ext Unused external definitions.
- gen General diagnostics.
- got Usage of goto statements.
- ini Possible problems with initialization.
- lan Effects of the language level.
- obs Features that are obsolete.
- ord Unspecified order of evaluation.
- par Unused parameters.
- por Nonportable language constructs.
- ppc Possible problems with using the preprocessor.
- ppt Trace of preprocessor actions.
- pro Missing function prototypes.
- rea Code that cannot be reached.
- ret Consistency of return statements.
- trd Possible truncation or loss of data or precision.
- tru Variable names truncated by the compiler.
- uni Uninitialized variables.
- use Unused auto and static variables.
-
- The /Wgroup options are described in the IBM VisualAge for C++ for Windows
- User's Guide.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.16. isolated_call ΓòÉΓòÉΓòÉ
-
- The #pragma isolated_call directive lists functions that do not alter data
- objects visible at the time of the function call.
-
- The #pragma isolated_call directive has the form:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇisolated_callΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓöÇidentifierΓöÇΓö┤ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- where identifier is a primary expression that can be an identifier, operator
- function, conversion function, or qualified name.
-
- The pragma must appear before calls to the functions in the identifier list.
- The identifiers listed must be declared before they are used in the pragma.
- They must be of type function or a typedef of function. If a name refers to an
- overloaded function, all variants of that function declared before the pragma
- are marked as isolated calls.
-
- The pragma informs the compiler that none of the functions listed has side
- effects. For example:
-
- Accessing a volatile object
- Modifying an external object
- Modifying a file
-
- or calling a function that does any of the above can be considered side
- effects.
-
- Essentially, any change in the state of the runtime environment is considered
- a side effect. Passing function arguments by reference is one side effect that
- is allowed, but in general, functions with side effects can give incorrect
- results when listed in #pragma isolated_call directives.
-
- Marking a function as isolated indicates to the optimizer that external and
- static variables cannot be changed by the called function and that references
- to storage can be deleted from the calling function where appropriate.
- Instructions can be reordered with more freedom, resulting in fewer pipeline
- delays and faster execution in the processor.
-
- Note: Instruction reordering might yield code with more values in
- general-purpose and/or floating-point registers maintained across the isolated
- call.
-
- When the isolated call is not located in a loop, the overhead of saving and
- restoring extra registers might not be worth the savings that result from
- deleting the storage references.
-
- Functions specified in the identifier list are permitted to examine external
- objects and return results that depend on the state of the runtime
- environment. The functions can also modify the storage pointed to by any
- pointer arguments passed to the function, that is, calls by reference. Do not
- specify a function that calls itself or relies on local static storage.
- Listing such functions in the #pragma isolated_call directive can give
- unpredictable results.
-
- The following example shows the use of the #pragma isolated_call directive.
- Because the function this_function does not have side effects, a call to it
- will not change the value of the external variable a. The compiler can assume
- that the argument to other_function has the value 6 and will not reload the
- variable from memory.
-
- int a, this_function(int); // Assumed to have no side effects
- #pragma isolated_call(this_function)
- that_function()
- {
- a = 6;
- this_function(7); // Call does not change the value of "a"
- other_function(a); // Argument "a" has the value 6
- }
-
- The isolated_call compiler option has the same effect as this pragma. The
- ignprag compiler option causes aliasing pragmas to be ignored. Use this option
- to debug applications containing the #pragma isolated_call directive. Compiler
- options are described in the IBM VisualAge for C++ for Windows User's Guide.
-
- Related Information
-
- Functions
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.17. langlvl ΓòÉΓòÉΓòÉ
-
- The #pragma langlvl directive lets you select elements of VisualAge for C++
- implementation.
-
- ΓöîΓöÇextendedΓöÇΓöÉ
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇlanglvlΓöÇΓöÇ(ΓöÇΓöÇΓö╝ΓöÇansiΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γö£ΓöÇcompatΓöÇΓöÇΓöÇΓöñ
- Γö£ΓöÇsaaΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇsaal2ΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- This directive can be specified only once in your source file, and must appear
- before any C or C++ code.
-
- The compiler defines preprocessor variables that are used in header files to
- define the language level. The options are:
-
- extended Defines the preprocessor variable __EXTENDED__. Allows ANSI and
- SAA C constructs and all VisualAge for C++ extensions.
-
- ansi Defines the preprocessor variables __ANSI__ and __STDC__. Allows
- only language constructs that conform to ANSI C standards. Note
- that for C++, the __STDC__ macro is set to 0, while for C it is
- set to 1.
-
- compat Defines the preprocessor variable __COMPAT__. Allows constructs
- supported by earlier versions of the C++ language, as well as ANSI
- constructs and VisualAge for C++ extensions. This language level
- is valid for C++ programs only.
-
- saa Defines the preprocessor variables __SAA__ and __SAAL2__. Allows
- only language constructs that conform to the most recent level of
- SAA C standards (currently Level 2). These include ANSI C
- constructs. This language level is valid for C programs only.
-
- saal2 Defines the preprocessor variable __SAAL2__. Allows only language
- constructs that conform to SAA Level 2 C standards. These include
- ANSI C constructs. This language level is valid for C programs
- only.
-
- The default language level is extended.
-
- You can also set the language level using the /Sa, /Sc, /S2, and /Se compiler
- options. These options are described in /S options
-
- Related Information
-
- Predefined Macro Names
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.18. library ΓòÉΓòÉΓòÉ
-
- The #pragma library directive causes the compiler to insert an INCLUDELIB
- library search record into the object file. This tells the linker to pull in
- the appropriate libraries at link time.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇlibraryΓöÇΓöÇ(ΓöÇΓöÇ"library_name"ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- where library_name is the default library to be made available for the program.
-
- The library names specified by #pragma library are imbedded in INCLUDELIB
- library search records in the order that they are encountered in the source.
- The library search records are inserted into the object file before the default
- library search records, so that the behavior at link time is the same as if the
- library name were specified at link time.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.19. linkage ΓòÉΓòÉΓòÉ
-
- The #pragma linkage directive identifies the linkage or calling convention used
- on a function call.
-
- This directive is valid for C programs only.
-
- Note: The #pragma linkage directive is obsolete in VisualAge for C++. Do not
- use it in new code. For your new applications, use linkage keywords to
- specify the calling convention for a function.
-
- Linkage keywords are easier to use than the #pragma linkage directive, and they
- let you declare both the function and its linkage type in one statement. See
- Linkage Keywords for more information on these keywords.
-
-
- ΓòÉΓòÉΓòÉ 9.13.20. map ΓòÉΓòÉΓòÉ
-
- The #pragma map directive tells the compiler that all references to an
- identifier are to be converted to "name".
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇmapΓöÇΓöÇ>
- >ΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇidentifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ,ΓöÇΓöÇ"name"ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇfunc_or_op_identifierΓöÇΓöÇ(ΓöÇΓöÇargument_listΓöÇΓöÇ)ΓöÇΓöÿ
-
- identifier A name of a data object or a nonoverloaded function
- with external linkage.
-
- func_or_op_identifier A name of a function or operator with internal linkage.
- The name can be qualified.
-
- argument_list A prototype list for the named function or operator.
-
- name The external name that is to be bound to the given
- object, function or operator.
-
- The directive can appear anywhere within a single compilation unit. It can
- appear before any declaration or definition of the named object, function, or
- operator. The identifiers appearing in the directive, including any type names
- used in the prototype argument list, are resolved as though the directive had
- appeared at file scope, independent of its actual point of occurrence.
-
- For example:
-
- int func(int);
-
- class X
- {
- public:
- void func(void);
- #pragma map(func, "funcname1") // maps ::func
- #pragma map(X::func, "funcname2") // maps X::func
- };
-
- The name must be fully decorated according to the linkage convention that
- applies to it. In the following example, the name func_alias is prefixed with
- a ? character to indicate _Optlink linkage:
-
- // File main.c - maps func to external name func_alias
- #pragma map(func, "?func_alias") // "?" indicates _Optlink linkage
-
- void func(void);
-
- int main(void)
- {
- func();
- return 0;
- }
-
- // File func.c - defines func_alias
- #include<stdio.h>
-
- void func_alias(void)
- {
- printf("A simple example of #pragma map\n");
- }
-
- See the IBM VisualAge for C++ for Windows Programming Guide for more
- information about using linkage keywords to specify the calling convention.
-
- In C++, you should not use #pragma map to map the following:
-
- C++ Member functions
- Overloaded functions
- Objects generated from templates
- Functions with C++ or builtin linkage
-
- Such mappings override the compiler-generated names, which could cause binder
- errors.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.21. margins ΓòÉΓòÉΓòÉ
-
- The #pragma margins directive specifies the columns in the input line that are
- to be scanned for input to the compiler.
-
- Note: This directive is valid for C programs only.
-
- ΓöîΓöÇnomarginsΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇΓö┤ΓöÇmarginsΓöÇΓöÇ(ΓöÇΓöÇleftΓöÇΓöÇ,ΓöÇΓöÇrightΓöÇΓöÇ)ΓöÇΓö┤ΓöÇΓöÇ><
-
- Use the #pragma margins directive if you want to have characters outside
- certain columns ignored in your source file. The compiler ignores any text in
- the source input that does not fall within the range specified in the
- directive.
-
- The variable left specifies the first column of the source input that is to be
- scanned, and must be between 1 and 65535, inclusive. The variable right
- specifies the last column of the source input that is to be scanned. It must be
- greater than or equal to left and less than or equal to 65535. An asterisk (*)
- can be assigned to right to indicate the last column of input.
-
- By default, the left margin is set to 1, and the right margin is set to
- infinity. The default for this directive is #pragma margins(), which has the
- effect of setting the right margin to infinity.
-
- The #pragma margins directive can be used with the #pragma sequence directive
- to specify the columns that are not to be scanned for sequence numbers. If the
- #pragma sequence settings do not fall within the #pragma margins settings, the
- #pragma sequence directive has no effect.
-
- You can also set margins using the /Sg option.
-
- Related Information
-
- sequence
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.22. pack ΓòÉΓòÉΓòÉ
-
- The #pragma pack directive specifies the alignment rules to use for the
- structures, unions, and classes that follow it. In C++, packing is performed on
- declarations or types. This is different from C, where packing is also
- performed on definitions.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇpackΓöÇΓöÇ(ΓöÇΓöÇ>
- >ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- Γö£ΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöñ
- Γöé ΓööΓöÇΓö¼ΓöÇpushΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ Γöé
- Γöé ΓööΓöÇpopΓöÇΓöÇΓöÿ ΓööΓöÇ,ΓöÇΓöÇidentifierΓöÇΓöÿ ΓööΓöÇ,ΓöÇΓöÇalignmentΓöÇΓöÿ Γöé
- ΓööΓöÇalignmentΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- push Stores the current boundary alignment value on the alignment stack.
-
- If #pragma pack (push) appears first in a module, packing is
- performed along the boundary specified by the /Sp compiler option,
- or the system default alignment of 8 bytes if the /Sp option is not
- set.
-
- pop Removes the current boundary alignment value from the alignment
- stack and makes that value the new alignment.
-
- Using pop on an empty stack causes a warning to be issued that the
- current alignment may change. Packing is performed along the
- boundary specified by the alignment value, if it has been specified.
- If not, packing is performed along the boundary specified by the /Sp
- compiler option, or the system default alignment of 8 bytes if the
- /Sp option is not set.
-
- identifier Associates a name with the new boundary alignment value. This value
- can be pushed or popped from the alignment stack.
-
- Using push with an identifier associates the identifier with a new
- alignment value.
-
- Using pop with an identifier pops all entries off the alignment
- stack up to and including the entry associated with identifier. The
- alignment value on the stack just before the entry associated with
- identifier. becomes the new alignment.
-
- If no matching identifier is on the stack, a warning is issued that
- the current alignment may change. The stack is not affected. Packing
- is performed along the boundary specified by the alignment value, if
- it has been specified. If not, packing is performed along the
- boundary specified by the /Sp compiler option, or the system default
- alignment of 8 bytes if the /Sp option is not set.
-
- alignment Is boundary alignment for packing in bytes. The alignment can be one
- of 1, 2, 4, 8, or 16 bytes.
-
- If no alignment is specified, packing is performed along the
- boundary specified by the /Sp compiler option, or the system default
- alignment of 8 bytes if the /Sp option is not set.
-
- Using push with an alignment value causes that value to be the new
- alignment.
-
- Using pop with an alignment value pops a value off the stack and
- sets the current alignment to alignment.
-
- The #pragma pack directive causes all structures, unions and classes that
- follow it in the program to be packed along a boundary specified in the
- directive, until another #pragma pack directive changes the packing boundary.
-
- If data types are by default packed along boundaries smaller than those
- specified by #pragma pack, they are still aligned along the smaller
- boundaries. For example, type char is always aligned along a 1-byte boundary,
- regardless of the value of #pragma pack.
-
- If more than one #pragma pack directive appears in a structure defined in an
- inlined function, the #pragma pack directive effective at the beginning of the
- structure takes precedence.
-
- The following table summarizes how each data type is packed for the #pragma
- pack alignment values:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé DATA TYPE Γöé #PRAGMA PACK ALIGNMENT VALUE Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Γöé 1 Γöé 2 Γöé 4 Γöé 8 Γöé 16 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé CHAR Γöé 1 Γöé 1 Γöé 1 Γöé 1 Γöé 1 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé SHORT Γöé 1 Γöé 2 Γöé 2 Γöé 2 Γöé 2 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé pointer Γöé 1 Γöé 2 Γöé 4 Γöé 4 Γöé 4 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé INT, LONG Γöé 1 Γöé 2 Γöé 4 Γöé 4 Γöé 4 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé LONG LONG Γöé 1 Γöé 2 Γöé 4 Γöé 8 Γöé 8 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé FLOAT, DOUBLE Γöé 1 Γöé 2 Γöé 4 Γöé 8 Γöé 8 Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé LONG DOUBLE Γöé 1 Γöé 2 Γöé 4 Γöé 8 Γöé 8 Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- For more information on the alignment of data types in structures, see the IBM
- VisualAge for C++ for Windows Programming Guide.
-
- For information on packing C structures, see _Packed Qualifier.
- Examples
-
- For example:
-
- #pragma pack(1)
-
- struct hester{ /* this structure is packed */
- char philip; /* along 1-byte boundaries */
- int mark;
- };
- .
- .
- .
- #pragma pack(2)
-
- struct jeff{ /* this structure is packed */
- float bill; /* along 2-byte boundaries */
- int *chris;
- }
- .
- .
- .
- #pragma pack()
-
- struct dor{ /* this structure is packed */
- double stephen; /* along the default boundaries */
- long alex;
- }
-
- The following example illustrates #pragma pack. In the example:
-
- (n) Is the current alignment
- [n n ...] Is the status of alignment stack
- {id} Is the identifier associated with the previously listed packing
- alignment
- D Is the default alignment for file (specified either by the /Sp
- option, or be the system default.)
-
- #pragma pack(1)
-
- struct T { // (1) [D]
- char c; // This struct is packed on 1 byte boundaries
- int i; // sizeof(T) = 5 bytes.;
- };
-
- #pragma pack ( push ) // (1) [1 D]
-
- struct S { // This struct is packed on 4 byte boundaries
- char c; // Assume /Sp=4
- int i; // sizeof(S) = 8 bytes.
- };
-
- #pragma pack ( push, 2 ) // (2) [1 1 D]
- // Packing: 2-byte boundary.
-
- #pragma pack ( push, level_1 ) // (2) [2{level_1} 1 1 D]
-
- #pragma pack ( push, level_2, 4 ) // (4) [2{level_2} 2{level_1} 1 1 D]
-
- #pragma pack ( push, level_3 ) // (4) [4{level_3} 2{level_2} 2{level_1} 1 1 D]
-
- #pragma pack ( 2 ) // (2) [4{level_3} 2{level_2} 2{level_1} 1 1 D]
-
- #pragma pack ( 1 ) // (1) [4{level_3} 2{level_2} 2{level_1} 1 1 D]
-
- Related Information
-
- _Packed Qualifier
- Structures
- Type Specifiers
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.23. page ΓòÉΓòÉΓòÉ
-
- The #pragma page directive skips the number of pages specified by pages of the
- generated source listing. If pages is not specified, the next page is started.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇpageΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇpagesΓöÇΓöÿ
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.24. pagesize ΓòÉΓòÉΓòÉ
-
- The #pragma pagesize directive sets the number of lines per page to lines for
- the generated source listing.
-
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇpagesizeΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇlinesΓöÇΓöÿ
-
- The value of lines must be between 16 and 32767, inclusive. The default page
- length is 66 lines.
-
- You can also use the /Lp compiler option to set the listing page size.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.25. priority ΓòÉΓòÉΓòÉ
-
- The #pragma priority directive specifies the order in which static objects are
- to be initialized at run time.
-
- C++ Note: This directive is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇpriorityΓöÇΓöÇ(ΓöÇΓöÇnΓöÇΓöÇ)ΓöÇΓöÇ><
-
- Where n is an integer literal in the range of INT_MIN to INT_MAX. The default
- value is 0. A negative value indicates a higher priority; a positive value
- indicates a lower priority.
-
- The first 1024 priorities (INT_MIN to INT_MIN + 1023) are reserved for use by
- the compiler and its libraries. The priority value specified applies to all
- runtime static initialization in the current compilation unit.
-
- Any global object declared before another object in a file is constructed
- first. Use #pragma priority to specify the construction order of objects across
- files.
-
- To ensure that the objects are always constructed from top to bottom in a file,
- the compiler enforces the restriction that the priority specified all objects
- before and all objects after it until the next #pragma is at that priority.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.26. sequence ΓòÉΓòÉΓòÉ
-
- The #pragma sequence directive defines the section of the input line that is to
- contain sequence numbers.
-
- Note: This directive is valid for C programs only.
-
- ΓöîΓöÇnosequenceΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- >>ΓöÇΓöÇΓöÇ#ΓöÇΓöÇΓöÇpragmaΓöÇΓöÇΓö┤ΓöÇsequenceΓöÇΓöÇ(ΓöÇΓöÇleftΓöÇΓöÇ,ΓöÇΓöÇrightΓöÇΓöÇ)ΓöÇΓö┤ΓöÇΓöÇ><
-
- If you are using a source file produced on a system that uses sequence numbers,
- you can use this option to have the sequence numbers ignored.
-
- The variable left specifies the column number of the left-hand margin. The
- value of left must be between 1 and 65535 inclusive, and must also be less than
- or equal to the value of right. The variable right specifies the column number
- of the right-hand margin. The value of right must be greater than or equal to
- left and less than or equal to 65535. An asterisk (*) can be assigned to right
- to indicate the last column of the line.
-
- The default for this directive is nosequence, which specifies there are no
- sequence numbers.
-
- The #pragma sequence directive can be used with the #pragma margins directive
- to specify the columns that are not to be scanned. If the #pragma sequence
- settings do not fall within the #pragma margins settings, the sequence
- directive has no effect.
-
- You can also set sequence numbers using the /Sq option.
-
- Related Information
-
- margins
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.27. skip ΓòÉΓòÉΓòÉ
-
- The #pragma skip directive skips the specified number of lines of the generated
- source listing. The value of lines must be a positive integer less than 255. If
- lines is omitted, one line is skipped.
-
- Note: This directive is valid for C programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇskipΓöÇΓöÇ(ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇlinesΓöÇΓöÿ
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.28. sourcedir ΓòÉΓòÉΓòÉ
-
- The #pragma sourcedir directive defines a new path to the directory containing
- the original source from which the compiler generates files in the TEMPINC
- directory.
-
- C++ Note: This directive is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇsourcedirΓöÇΓöÇ(ΓöÇΓöÇpathΓöÇΓöÇ)ΓöÇΓöÇ><
-
- Instead of searching the TEMPINC directory first for the original source of the
- include file, the pragma directs the compiler to the directory specified by the
- supplied path. The compiler automatically inserts the necessary #pragma
- sourcedir directives into the source files it generates in the TEMPINC
- directory.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.29. strings ΓòÉΓòÉΓòÉ
-
- The #pragma strings directive sets the storage type for strings. It specifies
- that the compiler can place strings into read-only memory or must place strings
- into read/write memory.
-
- ΓöîΓöÇwriteableΓöÇΓöÉ
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇstringsΓöÇΓöÇ(ΓöÇΓöÇΓö┤ΓöÇreadonlyΓöÇΓöÇΓö┤ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- This pragma must appear before any C or C++ code in a file.
-
- Strings are readonly by default.
-
- Related Information
-
- String Literals
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.30. subtitle ΓòÉΓòÉΓòÉ
-
- The #pragma subtitle directive places the text specified by subtitle on all
- subsequent pages of the generated source listing.
-
- Note: This directive is valid for C programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇsubtitleΓöÇΓöÇ(ΓöÇΓöÇ"subtitle"ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The string subtitle must be less than 255 characters.
-
- You can also use the /Lu compiler option to specify the listing subtitle.
-
- Related Information
-
- #pragma title
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.31. title ΓòÉΓòÉΓòÉ
-
- The #pragma title directive places the text specified by title on all
- subsequent pages of the generated source listing.
-
- Note: This directive is valid for C programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇtitleΓöÇΓöÇ(ΓöÇΓöÇ"title"ΓöÇΓöÇ)ΓöÇΓöÇ><
-
- The string title must be less than 255 characters.
-
- You can also use the /Lt compiler option to specify the listing title.
-
- Related Information
-
- #pragma subtitle
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.32. undeclared ΓòÉΓòÉΓòÉ
-
- The #pragma undeclared directive is used only by the compiler and only in
- template-include files. It is valid for C++ programs only.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇundeclaredΓöÇΓöÇ><
-
- In the template-include file, template functions that were explicitly declared
- in at least one compilation unit appear before this line. Template functions
- that were called, but never declared, appear after this line.
-
- For more information on template-include files, see "Using Templates in C++
- Programs" in the Programming Guide.
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 9.13.33. weak ΓòÉΓòÉΓòÉ
-
- The #pragma weak directive adds an alternate function name with weak binding
- for the function function_name.
-
- >>ΓöÇΓöÇ#ΓöÇΓöÇpragmaΓöÇΓöÇweakΓöÇΓöÇ(ΓöÇΓöÇfunction_nameΓöÇΓöÇ,ΓöÇΓöÇbackup_function_nameΓöÇΓöÇ)ΓöÇΓöÇ><
-
- If the definition for the function function_name is not found, the linker
- resolves the function call to the definition for the function
- backup_function_name. If the definition for function_name is found, the linker
- resolves the function call to the definition for function_name.
-
- If function_name is not referenced, neither function_name nor
- backup_function_name needs to be declared.
-
- If function_name is referenced, both function_name and backup_function_name
- must be declared.
-
- Note: Both functions must have full prototypes within the compilation unit.
- Neither function can be a C++ member function.
-
- In the following example, after the program is linked, the call to
- specialization resolves to the definition of generalization because no
- definition of specialization exists.
-
- #include <stdio.h>
- int generalization(int i) {
- printf("in generalization\n");
- }
- #pragma weak (specialization, generalization)
-
- int main() {
- printf("in main\n");
- return specialization(6);
- }
-
- Related Information
-
- Pragma Directives (#pragma)
- Preprocessor Directives
-
-
- ΓòÉΓòÉΓòÉ 10. C++ Classes ΓòÉΓòÉΓòÉ
-
- A C++ class is a mechanism for creating user-defined data types. It is similar
- to the C-language structure data type. In C, a structure is composed of a set
- of data members. In C++, a class type is like a C structure, except that a
- class is composed of a set of data members and an optional set of operations
- that can be performed on the class.
-
- In C++, a class type can be declared with the keywords union, struct, or class.
- A union object can hold any one of a set of named members. Structure and class
- objects hold a complete set of members. Each class type represents a unique set
- of class members including data members, member functions, and other type
- names. The default access for members depends on the class key:
-
- The members of a class declared with the class key class are private by
- default. A class is inherited privately by default.
- The members of a class declared with the class key struct are public be
- default. A structure is inherited publicly by default.
- The members of a union (declared with the class key union) are public by
- default. A union cannot be used as a base class in derivation. Base
- classes and derivation are described in C++ Inheritance.
-
- Once you create a class type, you can declare one or more objects of that
- class type.
-
- For example:
-
- class X
- { /* define class members here */ };
- void main()
- {
- X xobject1; // create an object of class type X
- X xobject2; // create another object of class type X
- }
-
- This chapter discusses the following topics:
-
- Declaring Class Objects
- Scope of Class Names
-
- Classes are also used in C++ to support polymorphic functions through
- overloaded functions (static compile time binding) and virtual functions
- (dynamic binding). C++ allows you to redefine standard operators and functions
- through the concept of overloading. Operator overloading facilitates data
- abstraction by allowing you to use classes as easily as built-in types.
-
- Related Information
-
- C++ Class Members and Friends
- C++ Inheritance
- C++ Overloading
- Virtual Functions
- Structures
- Unions
-
-
- ΓòÉΓòÉΓòÉ 10.1. Classes and Structures ΓòÉΓòÉΓòÉ
-
- The C++ class is an extension of the C-language structure. Because the only
- difference between a structure and a class is that structure members have
- public access by default and a class members have private access by default,
- you can use the keywords class or struct to define equivalent classes.
-
- For example, in the following code fragment, the class X is equivalent to the
- structure Y:
-
- // In this example, class X is equivalent to struct Y
-
- class X
- {
- int a; // private by default
- public:
- int f() { return a = 5; }; // public member function
- };
- struct Y
- {
- int f() { return a = 5; }; // public by default
- private:
- int a; // private data member
- };
-
- If you define a structure and then declare an object of that structure using
- the keyword class, the members of the object are still public by default.
-
- Example of Access for Classes and Structures
-
- An aggregate class is a class that has no user-defined constructors, no private
- or protected members, no base classes, and no virtual functions.
-
- Initialization of aggregate classes is described in Initializers.
-
- Related Information
-
- Structures
- Declaring Class Objects
- Scope of Class Names
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Access for Classes and Structures ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, main() has access to the members of X even though X
- is declared as using the keyword class:
-
- *
- ************************************************************************/
-
- // This example declares a structure, then declares a class
- // that is an object of the structure.
-
- #include <iostream.h>
-
- struct x {
- int a;
- int b;
- } ;
-
- class x X;
-
- void main() {
- X.a = 0;
- X.b = 1;
- cout << "Here are a and b " << X.a << " " << X.b << endl;
- }
-
-
- ΓòÉΓòÉΓòÉ 10.2. Declaring Class Objects ΓòÉΓòÉΓòÉ
-
- A class declaration creates a unique type class name.
-
- A class specifier is a type specifier used to declare a class. Once a class
- specifier has been seen and its members declared, a class is considered to be
- defined even if the member functions of that class are not yet defined. A class
- specifier has the following form:
-
- >>ΓöÇΓöÇΓö¼ΓöÇclassΓöÇΓöÇΓö¼ΓöÇΓöÇclass_nameΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ{ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ}ΓöÇΓöÇ><
- Γö£ΓöÇstructΓöÇΓöñ ΓööΓöÇ:base_classΓöÇΓöÿ ΓööΓöÇmember_listΓöÇΓöÿ
- ΓööΓöÇunionΓöÇΓöÇΓöÿ
-
- The member_list is optional. It specifies the class members, both data and
- functions, of the class class_name. If the member_list of a class is empty,
- objects of that class have a nonzero size. You can use a class_name within the
- member_list of the class specifier itself as long as the size of the class is
- not required. For more information, see Class Member Lists.
-
- The base_class is optional. It specifies the base class or classes from which
- the class class_name inherits members. If the base_class is not empty, the
- class class_name is called a derived class.
-
- The declarator for a class variable declared with the class, struct, or union
- keyword is an identifier. If the symbol * precedes the identifier, the
- identifier names a pointer to a class of the specified data type. If **
- precedes the identifier, the identifier names a pointer to a pointer to a class
- of the specified data type.
-
- If a constant expression enclosed in [ ] (brackets) follows the identifier, the
- identifier names an array of classes of the specified data type. If * precedes
- the identifier and a constant expression enclosed in [ ] follows the
- identifier, the identifier names an array of pointers to classes of the
- specified data type.
-
- Related Information
-
- Class Names
- Scope of Class Names
- Class Member Lists
- Derivation
-
-
- ΓòÉΓòÉΓòÉ 10.2.1. Class Names ΓòÉΓòÉΓòÉ
-
- A class name is a unique identifier that becomes a reserved word within its
- scope. Once a class name is declared, it hides other declarations of the same
- name within the enclosing scope.
-
- If a class name is declared in the same scope as a function, enumerator, or
- object with the same name, that class can be referred to by using an elaborated
- type specifier. In the following example, the elaborated type specifier is used
- to refer to the class print that is hidden by the later definition of the
- function print():
-
- class print
- {
- /* definition of class print */
- };
- void print (class print*); // redefine print as a function
- // . // prefix class-name by class-key
- // . // to refer to class print
- // .
- void main ()
- {
- class print* paper; // prefix class-name by class-key
- // to refer to class print
- print(paper); // call function print
- }
-
- You can use an elaborated type specifier with a class name to declare a class.
-
- For more information on elaborated type specifiers, see Incomplete Class
- Declarations.
-
- You can also qualify type names to refer to hidden type names in the current
- scope. You can reduce complex class name syntax by using a typedef to represent
- a nested class name.
-
- Example of Using a typedef for a Class Name
-
- Related Information
-
- Declaring Class Objects
- Scope of Class Names
- Nested Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Nested Class Specifier ΓòÉΓòÉΓòÉ
-
- The syntax of a nested class specifier is:
-
- >>ΓöÇΓöÇclass_nameΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ::nested_classΓöÇΓöÿ
-
- where class_name specifies the name of the enclosing class and nested-class
- specifies the name of the nested class. For more information, see Nested
- Classes.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Using a typedef for a Class Name ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, a typedef is used so that the simple name nested can
- be used in place of outside::middle::inside.
-
- *
- ************************************************************************/
-
- // This example illustrates a typedef used to simplify
- // a nested class name.
-
- #include <iostream.h>
-
- class outside {
- public:
- class middle {
- public:
- class inside {
- private:
- int a;
- public:
- inside(int a_init = 0): a(a_init) {}
- void printa();
- };
- };
- };
-
- typedef outside::middle::inside nested;
-
- void nested::printa() {
- cout << "Here is a " << this->a << endl;
- }
-
- void main() {
- nested n(9);
- n.printa();
- }
-
-
- ΓòÉΓòÉΓòÉ 10.2.2. Using Class Objects ΓòÉΓòÉΓòÉ
-
- You can use a class type to create instances or objects of that class type. For
- example, you can declare a class, structure, and union with class names X, Y,
- and Z respectively:
-
- class X { /* definition of class X */ };
- struct Y { /* definition of struct Y */ };
- union Z { /* definition of union Z */ };
-
- You can then declare objects of each of these class types. Remember that
- classes, structures, and unions are all types of C++ classes.
-
- void main()
- {
- X xobj; // declare a class object of class type X
- Y yobj; // declare a struct object of class type Y
- Z zobj; // declare a union object of class type Z
- }
-
- In C++, unlike C, you do not need to precede declarations of class objects with
- the keywords union, struct, and class unless the name of the class is hidden.
- For more information on hidden names, see Scope of Class Names.
-
- When you declare more than one class object in a declaration, the declarators
- are treated as if declared individually. For example, if you declare two
- objects of class S in a single declaration:
-
- class S { /* ... */ };
- void main()
- {
- S S,T; // declare two objects of class type S
- }
-
- this declaration is equivalent to:
-
- class S { /* ... */ };
- void main()
- {
- S S;
- class S T; // keyword class is required
- // since variable S hides class type S
- }
-
- but is not equivalent to:
-
- class S { /* ... */ };
- void main()
- {
- S S;
- S T; // error, S class type is hidden
- }
-
- You can also declare references to classes, pointers to classes, and arrays of
- classes.
-
- Examples of Declaring Class Objects
-
- Objects of class types that are not copy restricted can be assigned, passed as
- arguments to functions, and returned by functions. For more information, see
- Copying Class Objects.
-
- Related Information
-
- Objects
- Scope of Class Names
- Initialization by Constructor
- Copying Class Objects
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Declaring Class Objects ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In C++, unlike C, you do not need to precede declarations of class objects with
- the keywords union, struct, and class unless the name of the class is hidden.
- For example:
-
- *
- ************************************************************************/
-
- struct Y { /* ... */ };
- class X { /* ... */ };
- void main ()
- {
- int X; // hides the class name X
- Y yobj; // valid
- X xobj; // error, class name X is hidden
- class X xobj; // valid
- }
-
- /************************************************************************
- *
-
- The following example declares a reference, a pointer, and an array:
-
- *
- ************************************************************************/
-
- class X { /* ... */ };
- struct Y { /* ... */ };
- union Z { /* ... */ };
- void main()
- {
- X xobj;
- X &xref = xobj; // reference to class object of type X
- Y *yptr; // pointer to struct object of type Y
- Z zarray[10]; // array of 10 union objects of type Z
- }
-
-
- ΓòÉΓòÉΓòÉ 10.3. Scope of Class Names ΓòÉΓòÉΓòÉ
-
- A class declaration introduces the class name into the scope where it is
- declared. Any class, object, function or other declaration of that name in an
- enclosing scope is hidden. If a class name is declared in a scope where an
- object, function, or enumerator of the same name is also declared, you can only
- refer to the class by using the elaborated type specifier. The class key
- (class, struct, or union) must precede the class name to identify it.
-
- For example:
-
- // This example shows the scope of class names.
-
- class x { int a; }; // declare a class type class-name
-
- x xobject; // declare object of class type x
-
- int x(class x*) // redefine x to be a function
- {return 0;} // use class-key class to define
- // a pointer to the class type x
- // as the function argument
-
- void main()
- {
- class x* xptr; // use class-key class to define
- // a pointer to class type x
- xptr = &xobject; // assign pointer
- x(xptr); // call function x with pointer to class x
- }
-
- An elaborated type specifier can be used in the declaration of objects and
- functions. See Class Names for an example.
-
- An elaborated type specifier can also be used in the incomplete declaration of
- a class type to reserve the name for a class type within the current scope.
-
- Related Information
-
- Incomplete Class Declarations
- Nested Classes
- Local Classes
- Local Type Names
- Class Names
- Declaring Class Objects
- Scope in C
-
-
- ΓòÉΓòÉΓòÉ 10.3.1. Incomplete Class Declarations ΓòÉΓòÉΓòÉ
-
- An incomplete class declaration is a class declaration that does not define any
- class members. You cannot declare any objects of the class type or refer to the
- members of a class until the declaration is complete. However, an incomplete
- declaration allows you to make specific references to a class prior to its
- definition as long as the size of the class is not required.
-
- For example, you can define a pointer to the structure first in the definition
- of the structure second. Structure first is declared in an incomplete class
- declaration prior to the definition of second, and the definition of oneptr in
- structure second does not require the size of first:
-
- struct first; // incomplete declaration of struct first
-
- struct second // complete declaration of struct second
- {
- first* oneptr; // pointer to struct first refers to
- // struct first prior to its complete
- // declaration
-
- first one; // error, you cannot declare an object of
- // an incompletely declared class type
- int x, y;
- };
-
- struct first // complete declaration of struct first
- {
- second two; // define an object of class type second
- int z;
- };
-
- If you declare a class with an empty member list, it is a complete class
- declaration. For example:
-
- class X; // incomplete class declaration
- class Z {}; // empty member list
- class Y
- {
- public:
- X yobj; // error, cannot create an object of an
- // incomplete class type
- Z zobj; // valid
- };
-
- Related Information
-
- Declaring Class Objects
- Class Member Lists
- Scope of Class Names
-
-
- ΓòÉΓòÉΓòÉ 10.3.2. Nested Classes ΓòÉΓòÉΓòÉ
-
- A nested class is declared within the scope of another class. The name of a
- nested class is local to its enclosing class. Unless you use explicit
- pointers, references, or object names, declarations in a nested class can only
- use visible constructs, including type names, static members, and enumerators
- from the enclosing class and global variables.
-
- Member functions of a nested class follow regular access rules and have no
- special access privileges to members of their enclosing classes. Member
- functions of the enclosing class have no special access to members of a nested
- class.
-
- You can define member functions and static data members of a nested class in
- the global scope. For example, in the following code fragment, you can access
- the static members x and y and member functions f() and g() of the nested class
- nested by using a qualified type name. Qualified type names allow you to define
- a typedef to represent a qualified class name. You can then use the typedef
- with the :: (scope resolution) operator to refer to a nested class or class
- member, as shown in the following example:
-
- class outside
- {
- public:
- class nested
- {
- public:
- static int x;
- static int y;
- int f();
- int g();
- };
- };
- int outside::nested::x = 5;
- int outside::nested::f() { return 0; };
-
- typedef outside::nested outnest; // define a typedef
- int outnest::y = 10; // use typedef with ::
- int outnest::g() { return 0; };
- // . . .
-
- Related Information
-
- Class Names
- Declaring Class Objects
- Scope of Class Names
-
-
- ΓòÉΓòÉΓòÉ 10.3.3. Local Classes ΓòÉΓòÉΓòÉ
-
- A local class is declared within a function definition. The local class is in
- the scope of the enclosing function scope. Declarations in a local class can
- only use type names, enumerations, static variables from the enclosing scope,
- as well as external variables and functions.
-
- Examples of Local Classes
-
- Member functions of a local class have to be defined within their class
- definition. Member functions of a local class must be inline functions. Like
- all member functions, those defined within the scope of a local class do not
- need the keyword inline.
-
- A local class cannot have static data members. In the following example, an
- attempt to define a static member of a local class causes an error:
-
- void f()
- {
- class local
- {
- int f(); // error, local class has noninline
- // member function
- int g() {return 0;} // valid, inline member function
- static int a; // error, static is not allowed for
- // local class
- int b; // valid, nonstatic variable
- };
- }
- // . . .
-
- An enclosing function has no special access to members of the local class.
-
- Related Information
-
- Scope of Class Names
- Function Scope
- Inline Member Functions
- Inline Functions
- Local Type Names
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Local Classes ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example uses local classes.
-
- *
- ************************************************************************/
-
- int x; // global variable
- void f() // function definition
- {
- static int y; // static variable y can be used by
- // local class
- int x; // auto variable x cannot be used by
- // local class
- extern int g(); // extern function g can be used by
- // local class
-
- class local // local class
- {
- int g() { return x; } // error, local variable x
- // cannot be used by g
- int h() { return y; } // valid,static variable y
- int k() { return ::x; } // valid, global x
- int l() { return g(); } // valid, extern function g
- };
- }
-
- void main()
- {
- local* z; // error, local is undefined
- // .
- // .
- // .
- }
-
-
- ΓòÉΓòÉΓòÉ 10.3.4. Local Type Names ΓòÉΓòÉΓòÉ
-
- Local type names follow the same scope rules as other names. Scope rules are
- described in Scope in C++. Type names defined within a class declaration have
- class scope and cannot be used outside their class without qualification.
-
- If you use a class name, typedef name, or a constant name that is used in a
- type name, in a class declaration, you cannot redefine that name after it is
- used in the class declaration.
-
- For example:
-
- void main ()
- {
- typedef double db;
- struct st
- {
- db x;
- typedef int db; // error
- db y;
- };
- }
-
- The following declarations are valid:
-
- typedef float T;
- class s {
- typedef int T;
- void f(const T);
- };
-
- Here, function f() takes an argument of type s::T. However, the following
- declarations, where the order of the members of s has been reversed, cause an
- error:
-
- typedef float T;
- class s {
- void f(const T);
- typedef int T;
- };
-
- In a class declaration, you cannot redefine a name that is not a class name, or
- a typedef name to a class name or typedef name once you have used that name in
- the class declaration.
-
- Related Information
-
- Scope in C
- Declaring Class Objects
- Scope of Class Names
- Local Classes
- typedef
-
-
- ΓòÉΓòÉΓòÉ 11. C++ Class Members and Friends ΓòÉΓòÉΓòÉ
-
- This chapter describes class members and friends, including the following
- topics:
-
- Class Member Lists
- Data Members
- Class-Type Class Members
- Member Functions
- Member Scope
- Pointers to Members
- The this Pointer
- Static Members
- Member Access
- Friends
-
- Related Information
-
- C++ Classes
- C++ Inheritance
- Special C++ Member Functions
-
-
- ΓòÉΓòÉΓòÉ 11.1. Class Member Lists ΓòÉΓòÉΓòÉ
-
- An optional member list declares sub-objects called class members. Class
- members can be data, functions, classes, enumeration, bit fields, and typedef
- names. A member list is the only place you can declare class members. Friend
- declarations are not class members but must appear in member lists.
-
- The member list follows the class name and is placed between braces. It can
- contain access specifiers, member declarations, and member definitions.
-
- You can access members by using the class access . (dot) and -> (arrow)
- operators.
-
- An access specifier is one of public, private, or protected.
-
- A member declaration declares a class member for the class containing the
- declaration. For more information on declarations, see Declarations, and
- Declaring Class Objects.
-
- A member declaration that is a qualified name followed by a ; (semicolon) is
- used to restore access to members of base classes and is described in Access
- Declarations.
-
- A member declarator declares an object, function, or type within a declaration.
- It cannot contain an initializer. You can initialize a member by using a
- constructor or, if the member belongs to an aggregate class, by using a brace
- initializer list (a list surrounded by braces { }) in the declarator list. You
- must explicitly initialize a class containing constant or reference members
- with a brace initializer list or explicitly with a constructor.
-
- A member declarator of the form:
-
- [identifier] : constant-expression
-
- specifies a bit field.
-
- A pure specifier (= 0) indicates that a function has no definition. It is only
- used with virtual member functions and replaces the function definition of a
- member function in the member list. Pure specifiers are described in Virtual
- Functions.
-
- You can use the storage-class specifier static (but not extern, auto or
- register) in a member list.
-
- The order of mapping of class members in a member list is implementation
- dependent. For the VisualAge for C++ compiler, class members are allocated in
- the order they are declared. For more information, see the IBM VisualAge for
- C++ for Windows User's Guide.
-
- Related Information
-
- Member Access
- Dot Operator .
- Arrow Operator ->
- Declaring Class Objects
- Access Declarations
- Initialization by Constructor
- Virtual Functions
- Initializers
- Storage Class Specifiers
-
-
- ΓòÉΓòÉΓòÉ 11.2. Data Members ΓòÉΓòÉΓòÉ
-
- Data members include members that are declared with any of the fundamental
- types, as well as other types, including pointer, reference, array types, and
- user-defined types. You can declare a data member the same way as a variable,
- except that explicit initializers are not allowed inside the class definition.
-
- If an array is declared as a nonstatic class member, you must specify all of
- the dimensions of the array.
-
- Related Information
-
- Type Specifiers
- Class Member Lists
- Class-Type Class Members
- Static Members
- Member Access
-
-
- ΓòÉΓòÉΓòÉ 11.3. Class-Type Class Members ΓòÉΓòÉΓòÉ
-
- A class can have members that are of a class type or are pointers or references
- to a class type. Members that are of a class type must be of a class type that
- is previously declared. An incomplete class type can be used in a member
- declaration as long as the size of the class is not needed. For example, a
- member can be declared that is a pointer to an incomplete class type.
-
- A class X cannot have a member that is of type X, but it can contain pointers
- to X, references to X, and static objects of X. Member functions of X can take
- arguments of type X and have a return type of X. For example:
-
- class X
- {
- X();
- X *xptr;
- X &xref;
- static X xcount;
- X xfunc(X);
- };
-
- The bodies of member functions are always processed after the definition of
- their class is complete. For this reason, the body of a member function can
- refer to the name of the class that owns it. even if this requires information
- about the class definition.
-
- The language allows member functions to refer to any class member even if the
- member function definition appears before the declaration of that member in the
- class member list. For example,
-
- class Y
- {
- public:
- int a;
- Y ();
- private:
- int f() {return sizeof(Y);};
- void g(Y yobj);
- Y h(int a);
- };
-
- In this example, it is permitted for the inline function f() to make use of the
- size of class Y.
-
- Related Information
-
- Incomplete Class Declarations
- Member Functions
- Inline Member Functions
- C++ Classes
- Class Member Lists
-
-
- ΓòÉΓòÉΓòÉ 11.4. Member Functions ΓòÉΓòÉΓòÉ
-
- Member functions are operators and functions that are declared as members of a
- class. Member functions do not include operators and functions declared with
- the friend specifier. These are called friends of a class.
-
- The default linkage convention for member functions is _Optlink. Other linkage
- conventions are permitted to allow a parameters to be passed in a different
- order from _Optlink.
-
- A member function with linkage other than _Optlink still has a this pointer.
- The signature of a member function with linkage other than _Optlink is
- unchanged.
-
- The definition of a member function is within the scope of its enclosing class.
- The body of a member function is analyzed after the class declaration so that
- members of that class can be used in the member function body. When the
- function add() is called in the following example, the data variables a, b, and
- c can be used in the body of add().
-
- class x
- {
- public:
- int add() // inline member function add
- {return a+b+c;};
- private:
- int a,b,c;
- };
-
- There are several kinds of member functions:
-
- const and volatile member functions
- Virtual member functions
- Special member functions
- Inline member functions
- Member function templates
-
- Related Information
-
- Member Scope
- Static Member Functions
- Functions
- Class Member Lists
-
-
- ΓòÉΓòÉΓòÉ <hidden> const and volatile Member Functions ΓòÉΓòÉΓòÉ
-
- A member function declared with the const qualifier can be called for constant
- and nonconstant objects. A nonconstant member function can only be called for a
- nonconstant object. Similarly, a member function declared with the volatile
- qualifier can be called for volatile and nonvolatile objects. A nonvolatile
- member function can only be called for a nonvolatile object.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Virtual Member Functions ΓòÉΓòÉΓòÉ
-
- Virtual member functions are declared with the keyword virtual. They allow
- dynamic binding of member functions. Because all virtual functions must be
- member functions, virtual member functions are simply called virtual functions.
-
- If the definition of a virtual function is replaced by a pure specifier in the
- declaration of the function, the function is said to be declared pure. A class
- that has at least one pure virtual function is called an abstract class.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Special Member Functions ΓòÉΓòÉΓòÉ
-
- Special member functions are used to create, destroy, initialize, convert, and
- copy class objects. These include:
-
- Constructors
- Destructors
- Conversion constructors
- Conversion functions
- Copy constructors
-
-
- ΓòÉΓòÉΓòÉ <hidden> Inline Member Functions ΓòÉΓòÉΓòÉ
-
- A member function that is both declared and defined in the class member list is
- called an inline member function. Member functions containing a few lines of
- code are usually declared inline.
-
- An equivalent way to declare an inline member function is to declare it outside
- of the class declaration using the keyword inline and the :: (scope resolution)
- operator to identify the class the member function belongs to. For example:
-
- class Y
- {
- char* a;
- public:
- char* f() {return a;};
- };
-
- is equivalent to:
-
- class Z
- {
- char* a;
- public:
- char* f();
- };
- inline char* Z::f() {return a;}
-
- When you declare an inline function without the inline keyword and do not
- define it in the class member list, you cannot call the function before you
- define it. In the above example, you cannot call f() until after its
- definition.
-
- Inline member functions have internal linkage. Noninline member functions have
- external linkage.
-
- For more information, see Inline Functions.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Member Function Templates ΓòÉΓòÉΓòÉ
-
- Any member function (inlined or noninlined) declared within a class template is
- implicitly a function template. When a template class is declared, it
- implicitly generates template functions for each function defined in the class
- template. If a class template is instantiated, only the function templates
- whose instantiations will actually be used by the resulting template class are
- instantiated.
-
- For more information about member function templates, see Member Function
- Templates.
-
-
- ΓòÉΓòÉΓòÉ 11.5. Member Scope ΓòÉΓòÉΓòÉ
-
- Member functions and static members can be defined outside their class
- declaration if they have already been declared, but not defined, in the class
- member list. Nonstatic data members are defined when their class is
- instantiated. The declaration of a static data member is not a definition. The
- declaration of a member function is a definition if the body of the function is
- also given.
-
- Whenever the definition of a class member appears outside of the class
- declaration, the member name must be qualified by the class name using the ::
- (scope resolution) operator.
-
- Example of Defining a Member outside of the Class
-
- All member functions are in class scope even if they are defined outside their
- class declaration.
-
- The name of a class member is local to its class. Unless you use one of the
- class access operators, . (dot), or -> (arrow), or :: (scope resolution)
- operator, you can only use a class member in a member function of its class and
- in nested classes. You can only use types, enumerations and static members in a
- nested class without qualification with the :: operator.
-
- The order of search for a name in a member function body is:
-
- 1. Within the member function body itself
- 2. Within all the enclosing classes, including inherited members of those
- classes
- 3. Within the lexical scope of the body declaration
-
- Example of Member Function Search Path
-
- Note: When the containing classes are being searched, only the definitions of
- the containing classes and their base classes are searched. The scope
- containing the base class definitions (global scope, in this example) is not
- searched.
-
- Related Information
-
- Scope in C++
- C++ Scope Resolution Operator ::
- Member Functions
- Dot Operator .
- Arrow Operator ->
- Member Access
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Defining a Member ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example defines a member function outside of its class
- declaration.
-
- *
- ************************************************************************/
-
- // This example illustrates member scope.
-
- #include <iostream.h>
- class X
- {
- public:
- int a, b ; // public data members
- int add(); // member function declaration only
- };
- int a = 10; // global variable
- // define member function outside its class declaration
- int X::add() {return a + b;};
- // .
- // .
- // .
- void main()
- {
- int answer;
- X xobject;
- xobject.a = 1;
- xobject.b = 2;
- answer = xobject.add();
- cout << xobject.a << " + " << xobject.b << " = " << answer<<endl;
- }
-
- /************************************************************************
- *
-
- The output for this example is: 1 + 2 = 3
-
- Note: All member functions are in class scope even if they are defined outside
- their class declaration. In the above example, the member function add()
- returns the data member a, not the global variable a.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Member Function Search Path ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The search of the enclosing classes, including inherited members, is
- demonstrated in the following example:
-
- *
- ************************************************************************/
-
- class A { /* ... */ };
- class B { /* ... */ };
- class C { /* ... */ };
- class Z : A {
- class Y : B {
- class X : C { int f(); /* ... */ };
- };
- };
- int Z::Y::X f()
- {
- // ...
- j();
- // ...
- }
-
- /************************************************************************
- *
-
- In this example, the search for the name j in the definition of the function f
- follows this order:
-
- 1. In the body of the function f
- 2. In X and in its base class C
- 3. In Y and in its base class B
- 4. In Z and in its base class A
- 5. In the lexical scope of the body of f. In this case, this is global
- scope.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.6. Pointers to Members ΓòÉΓòÉΓòÉ
-
- Pointers to members allow you to refer to nonstatic members of class objects.
- You cannot use a pointer to member to point to a static class member because
- the address of a static member is not associated with any particular object. To
- point to a static class member, you must use a normal pointer.
-
- You can use pointers to member functions in the same manner as pointers to
- functions. You can compare pointers to member functions, assign values to them,
- and use them to call member functions. Note that a member function does not
- have the same type as a nonmember function that has the same number and type of
- arguments and the same return type.
-
- Example of Pointers to Members
-
- To reduce complex syntax, you can declare a typedef to be a pointer to a
- member. A pointer to a member can be declared and used as shown in the
- following code fragment:
-
- typedef void (X::*ptfptr) (int); // declare typedef
- void main ()
- {
- // ...
- ptfptr ptf = &X::f; // use typedef
- X xobject;
- (xobject.*ptf) (20); // call function
- }
-
- The pointer to member operators .* and ->* are used to bind a pointer to a
- member of a specific class object. Because the precedence of () (function call
- operator) is higher than .* and ->*, you must use parentheses to call the
- function pointed to by ptf.
-
- Related Information
-
- C++ Pointer to Member Operators .* ->*
- Pointers
- Static Members
- The this Pointer
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Pointers to Members ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- Pointers to members can be declared and used as shown in the following example:
-
- *
- ************************************************************************/
-
- // This example illustrates pointers to members.
-
- #include <iostream.h>
- class X
- {
- public:
- int a;
- void f(int b)
- {
- cout << "The value of b is "<< b << endl;
- }
- };
- // .
- // .
- // .
- void main ()
- {
- // declare pointer to data member
- int X::*ptiptr = &X::a;
-
- // declare a pointer to member function
- void (X::* ptfptr) (int) = &X::f;
-
- X xobject; // create an object of class type X
- xobject.*ptiptr = 10; // initialize data member
-
- cout << "The value of a is " << xobject.*ptiptr << endl;
- (xobject.*ptfptr) (20); // call member function
- }
-
- /************************************************************************
- *
-
- The output for this example is:
-
- The value of a is 10
- The value of b is 20
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.7. The this Pointer ΓòÉΓòÉΓòÉ
-
- The keyword this identifies a special type of pointer. When a nonstatic member
- function is called, the this pointer identifies the class object which the
- member function is operating on. You cannot declare the this pointer or make
- assignments to it.
-
- The type of the this pointer for a member function of a class type X, is X*
- const. If the member function is declared with the constant qualifier, the type
- of the this pointer for that member function for class X, is const X* const. If
- the member function is declared with the volatile qualifier, the type of the
- this pointer for that member function for class X is volatile X* const.
-
- this is passed as a hidden argument to all nonstatic member function calls and
- is available as a local variable within the body of all nonstatic functions.
-
- For example, you can refer to the particular class object that a member
- function is called for by using the this pointer in the body of the member
- function. The following code example produces the output a = 5:
-
- // This example illustrates the this pointer
-
- #include <iostream.h>
- class X
- {
- int a;
- public:
- // The 'this' pointer is used to retrieve 'xobj.a' hidden by
- // the automatic variable 'a'
- void Set_a(int a) { this->a = a; }
- void Print_a() { cout << "a = " << a << endl; }
- };
- void main()
- {
- X xobj;
- int a = 5;
- xobj.Set_a(a);
- xobj.Print_a();
- }
-
- Unless a class member name is hidden, using the class member name is equivalent
- to using the class member name qualified with the this pointer.
-
- Example of the this Pointer
-
- Related Information
-
- Pointers
- Member Functions
- Pointers to Members
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of the this Pointer ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows code using class members without the this pointer.
- The comments on each line show the equivalent code with the hidden use of the
- this pointer.
-
- *
- ************************************************************************/
-
- // This example uses class members without the this pointer.
-
- #include <string.h>
- #include <iostream.h>
- class X
- {
- int len;
- char *ptr;
- public:
- int GetLen() // int GetLen (X* const this)
- { return len; } // { return this->len; }
- char * GetPtr() // char * GetPtr (X* const this)
- { return ptr; } // { return this->ptr; }
- X& Set(char *);
- X& Cat(char *);
- X& Copy(X&);
- void Print();
- };
-
- X& X::Set(char *pc) // X& X::Set(X* const this, char *pc)
- {
- len = strlen(pc); // this->len = strlen(pc);
- ptr = new char[len]; // this->ptr =
- // new char[this->len];
- strcpy(ptr, pc); // strcpy(this->ptr, pc);
- return *this;
- }
-
- X& X::Cat(char *pc) // X& X::Cat(X* const this, char *pc)
- {
- len += strlen(pc); // this->len += strlen(pc);
- strcat(ptr,pc); // strcat(this->ptr,pc);
- return *this;
- }
-
- X& X::Copy(X& x) // X& X::Copy(X* const this, X& x)
- {
- Set(x.GetPtr()); // this->Set(x.GetPtr(&x));
- return *this;
- }
-
- void X::Print() // void X::Print(X* const this)
- {
- cout << ptr << endl; // cout << this->ptr << endl;
- }
- void main()
- {
- X xobj1;
- xobj1.Set("abcd").Cat("efgh");
- // xobj1.Set(&xobj1, "abcd").Cat(&xobj1, "efgh");
-
- xobj1.Print(); // xobj1.Print(&xobj1);
- X xobj2;
- xobj2.Copy(xobj1).Cat("ijkl");
- // xobj2.Copy(&xobj2, xobj1).Cat(&xobj2, "ijkl");
-
- xobj2.Print(); // xobj2.Print(&xobj2);
- }
-
- /************************************************************************
- *
-
- This example produces the following output:
-
- abcdefgh
- abcdefghijkl
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.8. Static Members ΓòÉΓòÉΓòÉ
-
- Class members can be declared using the storage-class specifier static in the
- class member list. Only one copy of the static member is shared by all objects
- of a class in a program. When you declare an object of a class having a static
- member, the static member is not part of the class object.
-
- A typical use of static members is for recording data common to all objects of
- a class. For example, you can use a static data member as a counter to store
- the number of objects of a particular class type that are created. Each time a
- new object is created, this static data member can be incremented to keep track
- of the total number of objects.
-
- The declaration of a static member in the member list of a class is not a
- definition. The definition of a static member is equivalent to an external
- variable definition. You must define the static member outside of the class
- declaration.
-
- For example:
-
- class X
- {
- public:
- static int i;
- };
- int X::i = 0; // definition outside class declaration
- // .
- // .
- // .
-
- A static member can be accessed from outside of its class only if it is
- declared with the keyword public. You can then access the static member by
- qualifying the class name using the :: (scope resolution) operator. In the
- following example:
-
- class X
- {
- public:
- static int f();
- };
- void main ()
- {
- X::f();
- }
-
- you can refer to the static member f() of class type X as X::f().
-
- Related Information
-
- static Storage Class Specifier
- Using the Class Access Operators with Static Members
- Static Data Members
- Static Member Functions
-
-
- ΓòÉΓòÉΓòÉ 11.8.1. Using the Class Access Operators with Static Members ΓòÉΓòÉΓòÉ
-
- You can also access a static member from a class object by using the class
- access operators . (dot) and -> (arrow). When a static member is accessed
- through a class access operator, the expression on the left of the . or ->
- operator is not evaluated.
-
- Example of Accessing Static Members
-
- A static member can be referred to independently of any association with a
- class object because there is only one static member shared by all objects of a
- class. A static member can exist even if no objects of its class have been
- declared.
-
- When you access a static member, the expression that you use to access it is
- not evaluated. In the following example, the external function f() returns
- class type X. The function f() can be used to access the static member i of
- class X. The function f() itself is not called.
-
- // This example shows that the expression used to
- // access a static member is not evaluated.
-
- class X
- {
- public:
- static int i;
- };
- int X::i = 10;
- X f() { /* ... */ }
- void main ()
- {
- int a;
- a = f().i; // f().i does not call f()
- }
-
- Related Information
-
- Static Members
- Dot Operator .
- Arrow Operator ->
- Static Data Members
- Static Member Functions
- x*
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Accessing Static Members ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example uses the class access operators to access static members.
-
- *
- ************************************************************************/
-
- // This example illustrates access to static
- // members with class access operators.
-
- #include <iostream.h>
- class X
- {
- static int cnt;
- public:
- // The following routines all set X's static variable cnt
- // and print its value.
- void Set_Show (int i)
- { X::cnt = i;
- cout << "X::cnt = " << X::cnt << endl; }
- void Set_Show (int i, int j )
- { this->cnt = i+j;
- cout << "X::cnt = " << X::cnt << endl; }
- void Set_Show (X& x, int i)
- { x.cnt = i;
- cout << "X::cnt = " << X::cnt << endl; }
- };
- int X::cnt;
- void main()
- {
- X xobj1, xobj2;
- xobj1.Set_Show(11);
- xobj1.Set_Show(11,22);
- xobj1.Set_Show(xobj2, 44);
- }
-
- /************************************************************************
- *
-
- The above example produces the following output:
-
- X::cnt = 11
- X::cnt = 33
- X::cnt = 44
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.8.2. Static Data Members ΓòÉΓòÉΓòÉ
-
- Static data members of global classes have external linkage and can be
- initialized in file scope like other global objects. Static data members follow
- the usual class access rules, except that they can be initialized in file
- scope. Static data members and their initializers can access other static
- private and protected members of their class. The initializer for a static data
- member is in the scope of the class declaring the member.
-
- The following example shows how you can initialize static members using other
- static members, even though these members are private:
-
- class C {
- static int i;
- static int j;
- static int k;
- static int l;
- static int m;
- static int n;
- static int p;
- static int q;
- static int r;
- static int s;
- static int f() { return 0; }
- int a;
- public:
- C() { a = 0; }
- };
-
- C c;
- int C::i = C::f(); // initialize with static member function
- int C::j = C::i; // initialize with another static data member
- int C::k = c.f(); // initialize with member function from an object
- int C::l = c.j; // initialize with data member from an object
- int C::s = c.a; // initialize with nonstatic data member
- int C::r = 1; // initialize with a constant value
-
- class Y : private C {} y;
-
- int C::m = Y::f();
- int C::n = Y::r;
- int C::p = y.r; // error
- int C::q = y.f(); // error
-
- The initializations of C::p and C::x cause errors because y is an object of a
- class that is derived privately from C, and its members are not accessible to
- members of C.
-
- You can only have one definition of a static member in a program. If a static
- data member is not initialized, it is assigned a zero default value. Local
- classes cannot have static data members.
-
- Example of Static Data Members
-
- Related Information
-
- Static Member Functions
- Static Members
- Using the Class Access Operators with Static Members
- External Linkage
- Member Access
- Local Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Static Data Members ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows the declaration, initialization, use, and scope of
- the static data member si and static member functions Set_si(int) and
- Print_si().
-
- *
- ************************************************************************/
-
- // This example shows the declaration, initialization,
- // use, and scope of a static data member.
-
- #include <iostream.h>
- class X
- {
- int i;
- static int si;
- public:
- void Set_i(int i) { this->i = i; }
- void Print_i() { cout << "i = " << i << endl; }
- // Equivalent to:
- // void Print_i(X* this)
- // { cout << "X::i = " << this->i << endl; }
- static void Set_si(int si) { X::si = si; }
-
- static void Print_si()
- {
- cout << "X::si = " << X::si << endl;
- }
- // Print_si doesn't have a 'this' pointer
- };
- int X::si = 77; // Initialize static data member
-
- void main()
- {
- X xobj;
- // Non-static data members and functions belong to specific
- // instances (here xobj) of class X
- xobj.Set_i(11);
- xobj.Print_i();
-
- // static data members and functions belong to the class and
- // can be accessed without using an instance of class X
- X::Print_si();
- X::Set_si(22);
- X::Print_si();
- }
-
- /************************************************************************
- *
-
- This example produces the following output:
-
- i = 11
- X::si = 77
- X::si = 22
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.8.3. Static Member Functions ΓòÉΓòÉΓòÉ
-
- You cannot have static and nonstatic member functions with the same names and
- the same number and type of arguments.
-
- A static member function does not have a this pointer. You can call a static
- member function using the this pointer of a nonstatic member function. In the
- following example, the nonstatic member function printall() calls the static
- member function f() using the this pointer:
-
- // This example illustrates a static member function f().
-
- #include <iostream.h>
- class c {
- static void f() { cout << "Here is i"
- << i << endl;}
- static int i;
- int j;
- public:
- c(int firstj): j(firstj) {}
- void printall();
- };
- void c::printall() {
- cout << "Here is j " << this->j << endl;
- this->f();
- }
- int c::i = 3;
- void main() {
- class c C(0);
- C.printall();
- }
-
- A static member function cannot be declared with the keyword virtual.
-
- A static member function can access only the names of static members,
- enumerators, and nested types of the class in which it is declared.
-
- Related Information
-
- Member Functions
- Using the Class Access Operators with Static Members
- Static Data Members
- Static Members
- The this Pointer
- Virtual Functions
-
-
- ΓòÉΓòÉΓòÉ 11.9. Member Access ΓòÉΓòÉΓòÉ
-
- Member access determines if a class member is accessible in an expression or
- declaration. Note that accessibility and visibility are independent. Visibility
- is based on the scoping rules of C++. A class member can be visible and
- inaccessible at the same time. This section describes how you control the
- access to the individual nonderived class members by using access specifiers
- when you declare class members in a member list.
-
- Related Information
-
- Access Declarations
- Inherited Member Access
- Class Member Lists
- Classes and Access Control
- Access Specifiers
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 11.9.1. Classes and Access Control ΓòÉΓòÉΓòÉ
-
- C++ facilitates data abstraction and encapsulation by providing access control
- for members of class types.
-
- For example, if you declare private data members and public member functions, a
- client program can only access the private members through the public member
- functions and friends of that class. Such a class would have data hiding
- because client programs do not have access to implementation details and are
- forced to use a public interface to manipulate objects of the class.
-
- You can control access to class members by using access specifiers. In the
- following example, the class abc has three private data members a, b, and c,
- and three public member functions add(), mult(), and the constructor abc(). The
- main() function creates an object danforth of the abc class and then attempts
- to print the value of the member a for this object:
-
- // This example illustrates class member access specifiers
-
- #include <iostream.h>
-
- class abc
- {
- private:
- int a, b, c;
- public:
- abc(int p1, int p2, int p3): a(p1), b(p2), c(p3) {}
- int add() { return a + b + c ; }
- int mult() { return a * b * c; }
- };
-
- void main() {
- abc danforth(1,2,3);
- cout << "Here is the value of a " << danforth.a << endl;
- // This causes an error because a is not
- // a public member and cannot be accessed
- // directly
- }
-
- Because class members are private by default, you can omit the keyword private
- in the definition of abc. Because a is not a public member, the attempt to
- access its value directly causes an error.
-
- Related Information
-
- Access Declarations
- Inherited Member Access
- Class Member Lists
- Member Access
- Access Specifiers
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 11.9.2. Access Specifiers ΓòÉΓòÉΓòÉ
-
- The three class member access specifiers have the following effect:
-
- public class members
- can be accessed by any function, file or class.
-
- private class members
- can be accessed only by member functions and friends of the class in
- which the member is declared.
-
- protected class members
- can be accessed only by member functions and friends of the class in
- which they are declared and by member functions and friends of
- classes derived with public or protected access from the class in
- which the protected members are declared. The access specifier
- protected can be used for nonbase class members, but it is
- equivalent to private unless it is used in a base class member
- declaration or in a base list.
-
- The default access for an individual class member depends on the class key
- used in the class declaration. Members of classes declared with the keyword
- class are private by default. Members of classes declared with the keyword
- struct or union are public by default.
-
- The access specifier protected is meaningful only in the context of
- derivation. You can control the access to inherited members (that is, base
- class members) by including access specifiers in the base list of the derived
- class declaration. You can also restore the access to an inherited member from
- a derived class by using an access declaration.
-
- Access for inherited members is described in Inherited Member Access.
-
- Member lists can include access specifiers as labels. Members declared after
- these labels have access as specified by the label they follow. An access
- specifier determines the access for members until another access specifier is
- used or until the end of the class declaration. You can use any number of
- access specifiers in any order.
-
- Examples of Access Specifiers
-
- Related Information
-
- Access Declarations
- Inherited Member Access
- Class Member Lists
- Member Access
- Classes and Access Control
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Access Specifiers ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows access specifiers in member lists.
-
- *
- ************************************************************************/
-
- class X
- {
- int a; // private data by default
- public:
- void f(int); // public function
- int b; // public data
- private:
- int c; // private data
- protected:
- void g(int); // protected function
- };
- struct Y
- {
- int a; // public data by default
- public:
- int b; // public data
- private:
- void g(int); // private function
- int c; // private data
- };
-
-
- ΓòÉΓòÉΓòÉ 11.10. Friends ΓòÉΓòÉΓòÉ
-
- A friend of a class X is a function or class that is granted the same access to
- X as the members of X. Functions declared with the friend specifier in a class
- member list are called friend functions of that class. Classes declared with
- the friend specifier in the member list of another class are called friend
- classes of that class.
-
- A class Y must be defined before any member of Y can be declared a friend of
- another class.
-
- You can declare an entire class as a friend.
-
- If the class has not been previously declared, use an elaborated type specifier
- and a qualified type specifier to specify the class name.
-
- If the friend class has been previously declared, you can omit the keyword
- class, as shown in the following example:
-
- class F;
- class X
- {
- public:
-
- X() {a=1; b=2;}
- private:
- int a, b;
- friend F; // elaborated-type-specifier not required
- };
-
- Examples of Friends
-
- Related Information
-
- Friend Scope
- Friend Access
- C++ Classes
- Member Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a friend Function ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, the friend function print is a member of class Y and
- accesses the private data members a and b of class X.
-
- *
- ************************************************************************/
-
- // This example illustrates a friend function.
-
- #include <iostream.h>
- class X;
- class Y
- {
- public:
- void print(X& x);
- };
- class X
- {
- public:
- X() {a=1; b=2;}
- private:
- int a, b;
- friend void Y::print(X& x);
- };
- void Y::print(X& x)
- {
- cout << "A is "<< x.a << endl;
- cout << "B is " << x.b << endl;
- }
- void main ()
- {
- X xobj;
- Y yobj;
- yobj.print(xobj);
- }
-
- /************************************************************************
- *
-
- In the following example, the friend class F has a member function print that
- accesses the private data members a and b of class X and performs the same task
- as the friend function print in the above example. Any other members declared
- in class F also have access to all members of class X. In the example, the
- friend class F has not been previously declared, so an elaborated type
- specifier and a qualified type specifier are used to specify the class name.
-
- *
- ************************************************************************/
-
- // This example illustrates a friend class.
-
- #include <iostream.h>
- class X
- {
- public:
-
- X() {a=1; b=2;} // constructor
- private:
- int a, b;
- friend class F; // friend class
- };
- class F
- {
- public:
- void print(X& x)
- {
- cout << "A is " << x.a << endl;
- cout << "B is " << x.b << endl;
- }
- };
- void main ()
- {
- X xobj;
- F fobj;
- fobj.print(xobj);
- }
-
- /************************************************************************
- *
-
- Both the above examples produce the following output:
-
- A is 1
- B is 2
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 11.10.1. Friend Scope ΓòÉΓòÉΓòÉ
-
- The name of a friend function or class first introduced in a friend declaration
- is not in the scope of the class granting friendship (also called the enclosing
- class) and is not a member of the class granting friendship.
-
- The name of a function first introduced in a friend declaration is in the scope
- of the first nonclass scope that contains the enclosing class. The body of a
- function provided in a friend declaration is handled in the same way as a
- member function defined within a class. Processing of the definition does not
- start until the end of the outermost enclosing class. In addition, unqualified
- names in the body of the function definition are searched for starting from the
- class containing the function definition.
-
- A class that is first declared in a friend declaration is equivalent to an
- extern declaration. For example:
-
- class B {};
- class A
- {
- friend class B; // global class B is a friend of A
- };
-
- If the name of a friend class has been introduced before the friend
- declaration, the compiler searches for a class name that matches the name of
- the friend class beginning at the scope of the friend declaration. If the
- declaration of a nested class is followed by the declaration of a friend class
- with the same name, the nested class is a friend of the enclosing class.
-
- The scope of a friend class name is the first nonclass enclosing scope. For
- example:
-
- class A {
- class B { // arbitrary nested class definitions
- friend class C;
- };
- };
-
- is equivalent to:
-
- class C;
- class A {
- class B { // arbitrary nested class definitions
- friend class C;
- };
- };
-
- If the friend function is a member of another class, you need to use the class
- member access operators. For example:
-
- class A
- {
- public:
- int f() { /* ... */ }
- };
- class B
- {
- friend int A::f();
- };
-
- Friends of a base class are not inherited by any classes derived from that base
- class.
-
- Related Information
-
- Scope of Class Names
- Friend Access
- Friends
- Nested Classes
- Derivation
-
-
- ΓòÉΓòÉΓòÉ 11.10.2. Friend Access ΓòÉΓòÉΓòÉ
-
- A friend of a class can access the private and protected members of that class.
- Normally, you can only access the private members of a class through member
- functions of that class, and you can only access the protected members of a
- class through member functions of a class or classes derived from that class.
-
- Friend declarations are not affected by access specifiers.
-
- Related Information
-
- Member Access
- Friend Scope
- Friends
-
-
- ΓòÉΓòÉΓòÉ 12. C++ Overloading ΓòÉΓòÉΓòÉ
-
- Overloading enables you to redefine functions and most standard C++ operators.
- Typically, you overload a function or operator if you want to extend the
- operations the function or operator performs to different data types.
-
- This section discusses:
-
- Overloading Functions
- Argument Matching in Overloaded Functions
- Overloading Operators
- Overloading Unary Operators
- Overloading Binary Operators
- Special Overloaded Operators
-
- Related Information
-
- Expressions and Operators
- Functions
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 12.1. Overloading Functions ΓòÉΓòÉΓòÉ
-
- You can overload a function by having multiple declarations of the same
- function name in the same scope. The declarations differ in the type and number
- of arguments in the argument list. When an overloaded function is called, the
- correct function is selected by comparing the types of the actual arguments
- with the types of the formal arguments.
-
- Consider a function print, which displays an int. As shown in the following
- example, you can overload the function print to display other types, for
- example, double and char*. You can have three functions with the same name,
- each performing a similar operation on a different data type.
-
- // This example illustrates function overloading.
-
- #include <iostream.h>
-
- void print(int i) { cout << " Here is int " << i << endl; }
- void print(double f) { cout << " Here is float "
- << f << endl; }
- void print(char* c) { cout << " Here is char* " << c << endl; }
- void main() {
- print(10); // calls print(int)
- print(10.10); // calls print(double)
- print("ten"); // calls print(char*)
- }
-
- Two function declarations are identical if all of the following are true:
-
- They have the same function name
- They are declared in the same scope
- They have identical argument lists
-
- When you declare a function name more than once in the same scope, the second
- declaration of the function name is interpreted by the compiler as follows:
-
- If the return type, argument types, and number of arguments of the two
- declarations are identical, the second declaration is considered a
- declaration of the same function as the first.
- If only the return types of the two function declarations differ, the
- second declaration is an error.
- If either the argument types or number of arguments of the two
- declarations differ, the function is considered to be overloaded.
-
- Restrictions on Overloaded Functions
-
- Related Information
-
- Functions
- Function Declarations
- Scope in C++
- Argument Matching in Overloaded Functions
- Member Functions
- C++ Inheritance
-
-
- ΓòÉΓòÉΓòÉ <hidden> Restrictions on Overloaded Functions ΓòÉΓòÉΓòÉ
-
- Functions that differ only in return type cannot have the same name.
-
- Two member functions that differ only in that one is declared with the
- keyword static cannot have the same name.
-
- A typedef is a synonym for another type, not a separate type. The
- following two declarations of spadina() are declarations of the same
- function:
-
- typedef int I;
- void spadina(float, int);
- void spadina(float, I);
-
- A member function of a derived class is not in the same scope as a member
- function in a base class with the same name. A derived class member hides
- a base class member with the same name.
-
- Argument types that differ only in that one is a pointer * and the other
- is an array [] are identical. The following two declarations are
- equivalent:
-
- f(char*);
- f(char[10]);
-
- Only the second and subsequent array dimensions are significant.
-
- The const and volatile type-specifiers on are ignored in distinguishing
- argument types when they appear at the outermost level of the argument
- type specification. The following declarations are equivalent:
-
- int f (int);
- int f (const int);
- int f (volatile int);
-
- Pointers and references to types considered distinct parameter types.
-
-
- ΓòÉΓòÉΓòÉ 12.2. Argument Matching in Overloaded Functions ΓòÉΓòÉΓòÉ
-
- When an overloaded function or overloaded operator is called, the compiler
- chooses the function declaration with the best match on all arguments from all
- the function declarations that are visible. The compiler compares the actual
- arguments of a function call with the formal arguments of all declarations of
- the function that are visible. For a best match to occur, the compiler must be
- able to distinguish a function that:
-
- Has at least as good a match on all arguments as any other function with
- the same name
- Has at least one better argument match than any other function with the
- same name
-
- If no such function exists, the call is not allowed. A call to an overloaded
- function has three possible outcomes. The compiler can find:
-
- An exact match
- No match
- An ambiguous match
-
- An ambiguous match occurs when the actual arguments of the function call match
- more than one overloaded function. The ANSI C++ working group has made the
- following clarifications of how and which built-in operators should
- participate in the operator overload resolution process:
-
- All appropriate built-in operators that are specified in section 13.6 of
- the September 1995 ANSI draft participate in the process.
-
- If you are using binary operators with pointer operands, the pointer
- operands must point to the same data type.
-
- The compiler distinguishes between integral/arithmetic and promoted
- integral/arithmetic type operands.
-
- The compiler only chooses the user-defined operator[] function for the
- subscripting expression x[y], if the overload resolution process chooses
- it as the best function match over the builtin operator.
-
- For builtin assignment operators, conversions of the left operand are
- restricted as follows:
-
- - No temporary objects are introduced to hold the left operand.
- - No user-defined conversions are applied to achieve a type match with
- the left operand.
-
- Argument matching can include performing standard and user-defined conversions
- on the arguments to match the actual arguments with the formal arguments. Only
- a single user-defined conversion is performed in a sequence of conversions on
- an actual argument. In addition, the best-matching sequence of standard
- conversions is performed on an actual argument. The best-matching sequence is
- the shortest sequence of conversions between two standard types. For example,
- the conversion:
-
- int -> float -> double
-
- can be shortened to the best-matching conversion sequence:
-
- int -> double
-
- because the conversion from int to double is allowed.
-
- Trivial Conversions do not affect the choice of conversion sequence.
- Conversion sequences are described in Sequence of Argument Conversions.
-
- Related Information
-
- Sequence of Argument Conversions
- Trivial Conversions
- Overloading Functions
- Overloading Operators
-
-
- ΓòÉΓòÉΓòÉ 12.2.1. Sequence of Argument Conversions ΓòÉΓòÉΓòÉ
-
- Argument-matching conversions occur in the following order:
-
- 1. An exact match in which the actual arguments match exactly (including a
- match with one or more trivial conversions) with the type and number of
- formal arguments of one declaration of the overloaded function
-
- 2. A match with promotions in which a match is found when one or more of the
- actual arguments is promoted
-
- 3. A match with standard conversions in which a match is found when one or
- more of the actual arguments is converted by a standard conversion
-
- 4. A match with user-defined conversions in which a match is found when one
- or more of the actual arguments is converted by a user-defined conversion
-
- 5. A match with ellipses
-
- Match through promotion follows the rules for Integral Promotions and Standard
- Type Conversions.
-
- You can override an exact match by using an explicit cast. In the following
- example, the second call to f() matches with f(void*):
-
- void f(int);
- void f(void*);
- void main()
- {
- f(0xaabb); // matches f(int);
- f((void*) 0xaabb); // matches f(void*)
- }
-
- The implicit first argument for a nonstatic member function or operator is the
- this pointer. It refers to the class object for which the member function is
- called. When you overload a nonstatic member function, the first implicit
- argument, the this pointer, is matched with the object or pointer used in the
- call to the member function. User-defined conversions are not applied in this
- type of argument matching for overloaded functions or operators.
-
- When you call an overloaded member function of class X using the . (dot) or ->
- (arrow) operator, the this pointer has type X* const. The type of the this
- pointer for a constant object is const X* const. The type of the this pointer
- for a volatile object is volatile X* const.
-
- Related Information
-
- Argument Matching in Overloaded Functions
- Trivial Conversions
- Implicit Type Conversions
- User-Defined Conversions
- The this Pointer
- Overloading Functions
- Overloading Operators
- Dot Operator .
- Arrow Operator ->
-
-
- ΓòÉΓòÉΓòÉ 12.2.2. Trivial Conversions ΓòÉΓòÉΓòÉ
-
- Functions cannot be distinguished if they have the same name and have arguments
- that differ only in that one is declared as a reference to a type and the other
- is that type. You cannot have two functions with the same name and with
- arguments differing only in this respect. Because the following two
- declarations cannot be distinguished, the second one causes an error:
-
- double f(double i); // declaration
-
- double f(double &i); // error
-
- However, functions with the same name having arguments that differ only in that
- one is a pointer or reference and the other is a pointer to const or const
- reference can be distinguished. Functions with the same name having arguments
- that differ only in that one is a pointer or reference and the other is a
- pointer to volatile or volatile reference can also be distinguished. For the
- purpose of finding a best match of arguments, functions that have a volatile or
- const match (not requiring a trivial conversion) are better than those that
- have a volatile or const mismatch.
-
- Related Information
-
- Argument Matching in Overloaded Functions
- Sequence of Argument Conversions
- Implicit Type Conversions
- User-Defined Conversions
- Overloading Functions
- Overloading Operators
-
-
- ΓòÉΓòÉΓòÉ 12.3. Overloading Operators ΓòÉΓòÉΓòÉ
-
- You can overload one of the standard C++ operators by redefining it to perform
- a particular operation when it is applied to an object of a particular class.
- Overloaded operators must have at least one argument that has class type. An
- overloaded operator is called an operator function and is declared with the
- keyword operator preceding the operator. Overloaded operators are distinct from
- overloaded functions, but, like overloaded functions, they are distinguished by
- the number and types of operands used with the operator.
-
- You can overload any of the following operators:
-
- + - * / % ^ & | ~
- ! = < > += -= *= /= %=
- ^= &= |= << >> <<= >>= == !=
- <= >= && || ++ -- , ->* ->
- () [] new delete
-
- where () is the function call operator and [] is the subscript operator.
-
- Consider the standard + (plus) operator. When this operator is used with
- operands of different standard types, the operators have slightly different
- meanings. For example, the addition of two integers is not implemented in the
- same way as the addition of two floating-point numbers. C++ allows you to
- define your own meanings for the standard C++ operators when they are applied
- to class types.
-
- Example of an Overloaded Operator
-
- You can overload both the unary and binary forms of:
-
- + - * &
-
- When an overloaded operator is a member function, the first operand is matched
- against the class type of the overloaded operator. The second operand, if one
- exists, is matched against the argument in the overloaded operator call.
-
- When an overloaded operator is a nonmember function, at least one operand must
- have class or enumeration type. The first operand is matched against the first
- argument in the overloaded operator call. The second operand, if one exists, is
- matched against the second argument in the overloaded operator call.
-
- The argument-matching conventions and rules described in Argument Matching in
- Overloaded Functions apply to overloaded operators.
-
- An overloaded operator must be either a member function, as shown in the
- following example:
-
- class X
- {
- public:
- X operator!();
- X& operator =(X&);
- X operator+(X&);
- };
- X X::operator!() { /* ... */ }
- X& X::operator=(X& x) { /* ... */ }
- X X::operator+(X& x) { /* ... */ }
-
- or take at least one argument of class, a reference to a class, an enumeration,
- or a reference to an enumeration, as shown below:
-
- class Y;
- {
- // .
- };
- class Z;
- {
- // .
- };
- Y operator!(Y& y);
- Z operator+(Z& z, int);
-
- Usually, overloaded operators are invoked using the normal operator syntax. You
- can also call overloaded operators explicitly by qualifying the operator name.
-
- Restrictions on Overloaded Operators
-
- Related Information
-
- Overloading Unary Operators
- Overloading Binary Operators
- Special Overloaded Operators
- Argument Matching in Overloaded Functions
- Overloading Functions
- Expressions and Operators
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of an Overloaded Operator ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, a class called complx is defined to model complex
- numbers, and the + (plus) operator is redefined in this class to add two
- complex numbers.
-
- *
- ************************************************************************/
-
- // This example illustrates overloading the plus (+) operator.
-
- #include <iostream.h>
- class complx
- {
- double real,
- imag;
- public:
- complx( double real = 0., double imag = 0.); // constructor
- complx operator+(const complx&) const; // operator+()
- };
- // define constructor
- complx::complx( double r, double i )
- {
- real = r; imag = i;
- }
- // define overloaded + (plus) operator
- complx complx::operator+ (const complx& c) const
- {
- complx result;
- result.real = (this->real + c.real);
- result.imag = (this->imag + c.imag);
- return result;
- }
- void main()
- {
- complx x(4,4);
- complx y(6,6);
- complx z = x + y; // calls complx::operator+()
- }
-
- /************************************************************************
- *
-
- For the class complx, described above, you can call the overloaded + (plus)
- operator either implicitly or explicitly as shown below.
-
- *
- ************************************************************************/
-
- // This example shows implicit and explicit calls
- // to an overloaded plus (+) operator.
-
- class complx
- {
- double real,
- imag;
- public:
- complx( double real = 0., double imag = 0.);
- complx operator+(const complx&) const;
- };
- // .
- // .
- // .
- void main()
- {
- complx x(4,4);
- complx y(6,6);
- complx u = x.operator+(y); // explicit call
- complx z = x + y; // implicit call to complx::operator+()
- }
-
-
- ΓòÉΓòÉΓòÉ 12.3.1. Restrictions on Overloaded Operators ΓòÉΓòÉΓòÉ
-
- The following C++ operators cannot be overloaded:
-
- . .* :: ?:
-
- You cannot overload the preprocessing symbols # and ##.
-
- You cannot change the precedence, grouping, or number of operands of the
- standard C++ operators.
-
- An overloaded operator (except for the function call operator) cannot
- have default arguments or an ellipsis in the argument list.
-
- You must declare the overloaded =, [], () and -> operators as nonstatic
- member functions to ensure that they receive lvalues as their first
- operands.
-
- The operators new and delete do not follow the general rules described in
- this section. Overloading new and delete is described in Overloaded new
- and delete.
-
- All operators except the = operator are inherited. Copy by Assignment
- describes the behavior of the assignment operator.
-
- Unless they are explicitly mentioned in Special Overloaded Operators,
- overloaded unary and binary operators follow the rules outlined in
- Overloading Unary Operators and Overloading Binary Operators.
-
- For more information on standard C and C++ operators, see Expressions and
- Operators.
-
-
- ΓòÉΓòÉΓòÉ 12.3.2. Overloading Unary Operators ΓòÉΓòÉΓòÉ
-
- You can overload a prefix unary operator by declaring a nonmember function
- taking one argument or a nonstatic member function taking no arguments.
-
- When you prefix a class object with an overloaded unary operator, for example:
-
- class X
- {
- // ...
- };
- void main ()
- {
- X x;
- !x; // overloaded unary operator
- }
-
- the operator function call !x can be interpreted as: x.operator!() or
- operator!(x) . depending on the declarations of the operator function. If both
- forms of the operator function have been declared, argument matching determines
- which interpretation is used.
-
- Related Information
-
- Overloading Binary Operators
- Overloading Operators
- Special Overloaded Operators
- Restrictions on Overloaded Operators
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 12.3.3. Overloading Binary Operators ΓòÉΓòÉΓòÉ
-
- You can overload a binary operator by declaring a nonmember function taking two
- arguments or a nonstatic member function taking one argument.
-
- When you use a class object with an overloaded binary operator, for example:
-
- class X
- {
- // ...
- };
- void main ()
- {
- X x;
- int y=10;
- x*y; // overloaded binary operator
- }
-
- the operator function call x*y can be interpreted as: x.operator*(y) or
- operator*(x,y) depending on the declarations of the operator function. If both
- forms of the operator function have been declared, argument matching determines
- which interpretation is used.
-
- Related Information
-
- Overloading Unary Operators
- Overloading Operators
- Special Overloaded Operators
- Restrictions on Overloaded Operators
- Binary Expressions
-
-
- ΓòÉΓòÉΓòÉ 12.4. Special Overloaded Operators ΓòÉΓòÉΓòÉ
-
- The following overloaded operators do not fully follow the rules for unary or
- binary overloaded operators:
-
- Assignment
- Function Call
- Subscripting
- Class Member Access
- Increment and Decrement
- new and delete
-
- Related Information
-
- Overloading Unary Operators
- Overloading Binary Operators
- Overloading Operators
- Restrictions on Overloaded Operators
- Member Functions
-
-
- ΓòÉΓòÉΓòÉ 12.4.1. Overloaded Assignment ΓòÉΓòÉΓòÉ
-
- You can only overload an assignment operator by declaring a nonstatic member
- function. The following example shows how you can overload the assignment
- operator for a particular class:
-
- class X
- {
- public:
- X();
- X& operator=(X&);
- X& operator=(int);
-
- };
- X& X::operator=(X& x) { /* ... */ }
- X& X::operator=(int i) { /* ... */ }
-
- void main()
- {
- X x1, x2;
- x1 = x2; // call x1.operator=(x2)
- x1 = 5; // call x1.operator=(5)
- }
-
- You cannot declare an overloaded assignment operator that is a nonmember
- function. Overloaded assignment operators are not inherited.
-
- If a copy assignment operator function is not defined for a class, the copy
- assignment operator function is defined by default as a memberwise assignment
- of the class members. If assignment operator functions exist for base classes
- or class members, these operators are used when the compiler generates default
- copy assignment operators. See Copy by Assignment for more information.
-
- For more information on standard assignment operators, see Assignment
- Expressions.
-
-
- ΓòÉΓòÉΓòÉ 12.4.2. Overloaded Function Calls ΓòÉΓòÉΓòÉ
-
- The operands are function_name and an optional expression_list. The operator
- function operator() must be defined as a nonstatic member function. You cannot
- declare an overloaded function call operator that is a nonmember function.
-
- If you make the following call for the class object x:
-
- x (arg1, arg2, arg3)
-
- it is interpreted as
-
- x.operator()(arg1, arg2, arg3)
-
- Unlike all other overloaded operators, you can provide default arguments and
- ellipses in the argument list for the function call operator. For example:
-
- class X
- {
- public:
- X& operator() (int = 5);
- };
-
- For more information on the standard function call operator, see Function
- Calls ( ).
-
-
- ΓòÉΓòÉΓòÉ 12.4.3. Overloaded Subscripting ΓòÉΓòÉΓòÉ
-
- An expression containing the subscripting operator has syntax of the form:
-
- identifier [ expression ]
-
- and is considered a binary operator. The operands are identifier and
- expression. The operator function operator[] must be defined as a nonstatic
- member function. You cannot declare an overloaded subscript operator that is a
- nonmember function.
-
- A subscripting expression for the class object x:
-
- x [y]
-
- is interpreted as x.operator[](y). It is not interpreted as operator[](x,y)
- because it is defined as a nonstatic member function.
-
- For more information on the standard subscripting operator, see Array
- Subscript[ ] (Array Element Specification).
-
-
- ΓòÉΓòÉΓòÉ 12.4.4. Overloaded Class Member Access ΓòÉΓòÉΓòÉ
-
- An expression containing the class member access -> (arrow) operator has syntax
- of the form:
-
- identifier -> name-expression
-
- and is considered a unary operator. The operator function operator->() must be
- defined as a nonstatic member function.
-
- The following restrictions apply to class member access operators:
-
- You cannot declare an overloaded arrow operator that is a nonmember
- function.
- You cannot overload the class member access . (dot) operator.
-
- Consider the following example of overloading the -> (arrow) operator:
-
- class Y
- {
- public:
- void f();
- };
- class X
- {
- public:
- Y* operator->();
- };
- X x;
- x->f();
-
- Here x->f() is interpreted as: ( x.operator->() )-> f() .
-
- x.operator->() must return either a reference to a class object or a class
- object for which the overloaded operator-> function is defined or a pointer to
- any class. If the overloaded operator-> function returns a class type, the
- class type must not be the same as the class declaring the function, and the
- class type returned must contain its own definition of an overloaded ->
- operator function.
-
- For more information on the standard class member access arrow operator, see
- Arrow Operator ->.
-
-
- ΓòÉΓòÉΓòÉ 12.4.5. Overloaded Increment and Decrement ΓòÉΓòÉΓòÉ
-
- The prefix increment operator ++ can be overloaded for a class type by
- declaring a nonmember function operator with one argument of class type or a
- reference to class type, or by declaring a member function operator with no
- arguments.
-
- In the following example, the increment operator is overloaded in both ways:
-
- // This example illustrates an overloaded prefix increment operator.
-
- class X
- {
- int a;
- public:
- operator++(); // member prefix increment operator
- };
- class Y { /* ... */ };
- operator++(Y& y); // nonmember prefix increment operator
-
- // Definitions of prefix increment operator functions
- // ...
-
- void main()
- {
- X x;
- Y y;
- ++x; // x.operator++
- x.operator++(); // x.operator++
- operator++(y); // nonmember operator++
- ++y; // nonmember operator++
- }
-
- The postfix increment operator ++ can be overloaded for a class type by
- declaring a nonmember function operator operator++() with two arguments, the
- first having class type and the second having type int. Alternatively, you can
- declare a member function operator operator++() with one argument having type
- int. The compiler uses the int argument to distinguish between the prefix and
- postfix increment operators. For implicit calls, the default value is zero.
-
- For example:
-
- // This example illustrates an overloaded postfix increment operator.
-
- class X
- {
- int a;
- public:
- operator++(int); // member postfix increment operator
- };
- operator++(X x, int i); // nonmember postfix increment operator
-
- // Definitions of postfix increment operator functions
- // ...
-
- void main()
- {
- X x;
- x++; // x.operator++
- // default zero is supplied by compiler
- x.operator++(0); // x.operator++
- operator++(x,0); // nonmember operator++
- }
-
- The prefix and postfix decrement operators follow the same rules as their
- increment counterparts.
-
- For more information on the standard postfix and prefix increment operators,
- see Increment ++. For more information on the standard postfix and prefix
- decrement operators, see Decrement - -.
-
-
- ΓòÉΓòÉΓòÉ 12.4.6. Overloaded new and delete ΓòÉΓòÉΓòÉ
-
- You can implement your own memory management scheme for a class by overloading
- the operators new and delete. The overloaded operator new must return a void*,
- and its first argument must have type size_t. The overloaded operator delete
- must return a void type, and its first argument must be void*. The second
- argument for the overloaded delete operator is optional and, if present, it
- must have type size_t. You can only define one delete operator function for a
- class.
-
- Type size_t is an implementation dependent unsigned integral type defined in
- <stddef.h>. For more information about size_t, see the IBM VisualAge for C++
- for Windows User's Guide.
-
- The size argument is required because a class can inherit an overloaded new
- operator. The derived class can be a different size than the base class. The
- size argument ensures that the correct amount of storage space is allocated or
- deallocated for the object.
-
- When new and delete are overloaded within a class declaration, they are static
- member functions whether they are declared with the keyword static or not. They
- cannot be virtual functions.
-
- You can access the standard, nonoverloaded versions of new and delete within a
- class scope containing the overloading new and delete operators by using the ::
- (scope resolution) operator to provide global access.
-
- For more information on the class member operators new and delete, see Free
- Store. For more information on the standard new and delete operators, see C++
- new Operator and C++ delete Operator.
-
-
- ΓòÉΓòÉΓòÉ 13. Special C++ Member Functions ΓòÉΓòÉΓòÉ
-
- This chapter introduces the special member functions that are used to create,
- destroy, convert, initialize, and copy class objects. This chapter discusses:
-
- Constructors
- Destructors
- Free Store
- Temporary Objects
- User-Defined Conversions
- Initialization by Constructor
- Copying Class Objects
-
- Related Information
-
- Functions
- C++ Classes
- C++ Class Members and Friends
- C++ Overloading
- C++ Inheritance
-
-
- ΓòÉΓòÉΓòÉ 13.1. Constructors and Destructors Overview ΓòÉΓòÉΓòÉ
-
- Because classes have complicated internal structures, including data and
- functions, object initialization and cleanup for classes is much more
- complicated than it is for simple data structures. Constructors and destructors
- are special member functions of classes that are used to construct and destroy
- class objects. Construction may involve memory allocation and initialization
- for objects. Destruction may involve cleanup and deallocation of memory for
- objects.
-
- Like other member functions, constructors and destructors are declared within a
- class declaration. They can be defined inline or external to the class
- declaration. Constructors can have default arguments. Unlike other member
- functions, constructors can have member initialization lists. The following
- restrictions apply to constructors and destructors:
-
- Constructors and destructors do not have return types nor can they return
- values.
- References and pointers cannot be used on constructors and destructors
- because their addresses cannot be taken.
- Constructors cannot be declared with the keyword virtual.
- Constructors and destructors cannot be declared static, const, or
- volatile.
- Unions cannot contain class objects that have constructors or
- destructors.
-
- Constructors and destructors obey the same access rules as member functions.
- For example, if a constructor is declared with the keyword protected, only
- derived classes and friends can use it to create class objects. Class member
- access is described in Member Access.
-
- The compiler automatically calls constructors when defining class objects and
- calls destructors when class objects go out of scope. A constructor does not
- allocate memory for the class object its this pointer refers to, but may
- allocate storage for more objects than its class object refers to. If memory
- allocation is required for objects, constructors can explicitly call the new
- operator. During cleanup, a destructor may release objects allocated by the
- corresponding constructor. To release objects, use the delete operator.
-
- Derived classes do not inherit constructors or destructors from their base
- classes, but they do call the constructor and destructor of base classes.
- Destructors can be declared with the keyword virtual.
-
- Constructors are also called when local or temporary class objects are
- created, and destructors are called when local or temporary objects go out of
- scope.
-
- You can call member functions from constructors or destructors. You can call a
- virtual function, either directly or indirectly, from a constructor or
- destructor. In this case, the function called is the one defined in the class
- or base class containing the constructor (or destructor), but not a function
- defined in any class derived from the class being constructed. This avoids the
- possibility of accessing an unconstructed object from a constructor or
- destructor.
-
- The typeid and dynamic_cast operators for runtime type identification (RTTI)
- can be used in constructors or destructors, or in functions called from a
- constructor or destructor.
-
- If the operand of typeid used refers to an object under construction or
- destruction, typeid returns the type_info representing the class of the
- constructor or destructor.
-
- If the operand of dynamic_cast refers to an object under construction or
- destruction, the object is considered to be a complete object that has the
- type of the constructor or destructor's class.
-
- The result of the typeid and dynamic_cast operations is undefined if the
- operand refers to an object under construction or destruction, and the static
- type of the operand is not an object of the constructor or destructor's class
- or one of its bases.
-
- Related Information
-
- Constructors
- Destructors
- Virtual Functions
- Member Access
- C++ new Operator
- C++ delete Operator
- dynamic_cast<>()
- typeid()
- Inheritance Overview
- Virtual Functions
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 13.1.1. Constructors ΓòÉΓòÉΓòÉ
-
- A constructor is a member function with the same name as its class. For
- example:
-
- class X
- {
- public:
- X(); // constructor for class X
- };
-
- Constructors are used to create, and can initialize, objects of their class
- type. Initialization of class objects using constructors is described in
- Initialization by Constructor.
-
- A default constructor is a constructor that either has no arguments, or, if it
- has arguments, all the arguments have default values. If no user-defined
- constructor exists for a class and one is needed, the compiler creates a
- default constructor, with public access, for that class. No default constructor
- is created for a class that has any constant or reference type members.
-
- Like all functions, a constructor can have default arguments. They are used to
- initialize member objects. If default values are supplied, the trailing
- arguments can be omitted in the expression list of the constructor. Note that
- if a constructor has any arguments that do not have default values, it is not a
- default constructor.
-
- A copy constructor is used to make a copy of one class object from another
- class object of the same class type. A copy constructor is called with a single
- argument that is a reference to its own class type. You cannot use a copy
- constructor with an argument of the same type as its class; you must use a
- reference. You can provide copy constructors with additional default arguments.
- If a user-defined copy constructor does not exist for a class and one is
- needed, the compiler creates a copy constructor, with public access, for that
- class. It is not created for a class if any of its members or base classes have
- an inaccessible copy constructor.
-
- If a class has a base class or members with constructors when it is
- constructed, the constructor for the base class is called, followed by any
- constructors for members. The constructor for the derived class is called last.
- Virtual base classes are constructed before nonvirtual base classes. When more
- than one base class exists, the base class constructors are called in the order
- that their classes appear in the base list. For more information, see
- Construction Order of Derived Class Objects.
-
- Examples of Constructors and Construction Order
-
- You cannot call constructors directly. You use a function style cast to
- explicitly construct an object of the specified type.
-
- Example of Explicitly Constructing an Object
-
- Related Information
-
- Destructors
- Constructors and Destructors Overview
- Construction Order of Derived Class Objects
- Default Arguments in C++ Functions
- References
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Explicitly Constructing an Object ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, a constructor is used as an initializer to create a
- named object.
-
- *
- ************************************************************************/
-
- #include <iostream.h>
- class X
- {
- public:
-
- X (int, int , int = 0); // constructor with default argument
- private:
- int a, b, c;
- int f();
- };
- X::X (int i, int j, int k) { a = i; b = j; c = k; }
-
- void main ()
- {
- X xobject = X(1,2,3); // explicitly create and initialize
- // named object with constructor call
- }
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Constructors and Construction Order ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following code fragment shows two classes with constructors, default
- constructors, and copy constructors:
-
- class X
- {
- public:
- X(); // default constructor, no arguments
- X(int, int , int = 0); // constructor
- X(const X&); // copy constructor
- X(X); // error, incorrect argument type
- };
- class Y
- {
- public:
- Y( int = 0); // default constructor with one
- // default argument
- Y(const Y&, int = 0); // copy constructor
- };
-
- When more than one base class exists, the base class constructors are called in
- the order that their classes appear in the base list, as shown in the following
- example:
-
- *
- ************************************************************************/
-
- class B1 { public: B1(); };
- class B2
- {
- public:
- B2();
- B1 b1obj;
- };
- class B3 { public: B3(); };
- // ...
- class D : public B1, public B2, public B3
- {
- public:
- D();
- ~D();
- };
-
- void main ()
- {
- D object;
- }
-
- /************************************************************************
- *
-
- In the above example, the constructors for object are called in the following
- order:
-
- B1(); // first base constructor declared
- B1(); // member constructor for B2::b1obj
- B2(); // second base constructor declared
- B3(); // last base constructor declared
- D(); // derived constructor called last
-
- Note that the construction of class D involves construction of the base classes
- B1, B2, and B3. The construction of base class B2 involves the construction of
- its class B1 member object. When class B2 is constructed, the constructor for
- class B1 is called in addition to B2's own constructor.
-
- As explained above, the second call to the constructor of B1 followed by the
- call to the constructor of B2 is part of the construction of B2.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 13.1.2. Destructors ΓòÉΓòÉΓòÉ
-
- A destructor is a member function with the same name as its class prefixed by a
- ~ (tilde).
-
- For example:
-
- class X
- {
- public:
- X(); // constructor for class X
- ~X(); // destructor for class X
- };
-
- A destructor takes no arguments and has no return type. Its address cannot be
- taken. Destructors cannot be declared const, volatile, or static. A destructor
- can be declared virtual or pure virtual. A union cannot have as a member an
- object of a class with a destructor.
-
- Destructors are usually used to deallocate memory and do other cleanup for a
- class object and its class members when the object is destroyed. A destructor
- is called for a class object when that object passes out of scope or is
- explicitly deleted.
-
- Class members that are class types can have their own destructors. Both base
- and derived classes can have destructors, although destructors are not
- inherited. If a base class or a member of a base class has a destructor and a
- class derived from that base class does not declare a destructor, a default
- destructor is generated. The default destructor calls the destructors of the
- base class and members of the derived class. Default destructors are generated
- with default public access.
-
- Destructors are called in the reverse order to constructors:
-
- 1. The destructor for a class object is called before destructors for
- members and bases are called.
- 2. Destructors for nonstatic members are called before destructors for base
- classes are called.
- 3. Destructors for nonvirtual base classes are called before destructors for
- virtual base classes are called.
-
- When an exception is thrown for a class object with a destructor, the
- destructor for the temporary object thrown is not called until control passes
- out of the catch block. For more information, see Constructors and Destructors
- in Exception Handling.
-
- Destructors are implicitly called when an automatic or temporary object passes
- out of scope. They are implicitly called at program termination for
- constructed external and static objects. Destructors are invoked when you use
- the delete operator for objects created with the new operator.
-
- Example of Destructors
-
- You can use a destructor explicitly to destroy objects, although this practice
- is not recommended. If an object has been placed at a specific address by the
- new operator, you can call the destructor of the object explicitly to destroy
- it. An explicitly called destructor cannot delete storage.
-
- Note: You can only call destructors for class types. You cannot call
- destructors for simple types. The call to the destructor in the following
- example causes the compiler to issue a warning:
-
- int * ptr;
- ptr -> int::~int(); // warning
-
- Related Information
-
- Constructors and Destructors Overview
- Constructors
- Virtual Functions
- Constructors and Destructors in Exception Handling
- C++ new Operator
- C++ delete Operator
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Destructors ΓòÉΓòÉΓòÉ
-
- /***********************************************************************
- *
-
- The following example shows the use of destructors:
-
- *
- ************************************************************************/
-
- #include <string.h>
- class Y
- {
- private:
- char * string;
- int number;
- public:
- Y(const char* n,int a); // constructor
- ~Y() { delete[] string; } // destructor
- };
- Y::Y(const char* n, int a) // define class Y constructor
- {
- string = strcpy(new char[strlen(n) + 1 ], n);
- number = a;
- }
- void main ()
- {
- Y yobj = Y("somestring", 10); // create and initialize
- // object of class Y
- // ...
- // destructor ~Y is called before control returns from main()
- }
-
-
- ΓòÉΓòÉΓòÉ 13.2. Free Store ΓòÉΓòÉΓòÉ
-
- Free store is used for dynamic allocation of memory. The new and delete
- operators are used to allocate and deallocate free store, respectively. You can
- define your own versions of new and delete for a class by overloading them. You
- can supply the new and delete operators with additional arguments. You can also
- use the /Tm option to enable the debug versions of these operators. See Debug
- Versions of new and delete for more information on these versions. When new and
- delete operate on class objects, the class member operator functions new and
- delete are called, if they have been declared.
-
- If you create a class object with the new operator, one of the operator
- functions operator new() or operator new[]() (if they have been declared) is
- called to create the object. An operator new() or operator new[]() for a class
- is always a static class member, even if it is not declared with the keyword
- static. It has a return type void* and its first argument must be the size of
- the object type and have type size_t. It cannot be virtual.
-
- Type size_t is an implementation dependent unsigned integral type defined in
- <stddef.h>. For more information about size_t, see the IBM VisualAge for C++
- for Windows User's Guide.
-
- When you overload the new operator, you must declare it as a class member,
- returning type void*, with first argument size_t, as described above. You
- supply additional arguments in the declaration of operator new() or operator
- new[](). Use the placement syntax to specify values for these arguments in an
- allocation expression.
-
- The delete operator destroys an object created by the new operator. The operand
- of delete must be a pointer returned by new. If delete is called for an object
- with a destructor, the destructor is invoked before the object is deallocated.
-
- If you destroy a class object with the delete operator, the operator function
- operator delete() or operator delete[]() (if they have been declared) is called
- to destroy the object. An operator delete() or operator delete[]() for a class
- is always a static member, even if it is not declared with the keyword static.
- Its first argument must have type void*. Because operator delete() and operator
- delete[]() have a return type void, they cannot return a value. They cannot be
- virtual.
-
- When you overload the delete operator, you must declare it as class member,
- returning type void, with first argument having type void*, as described above.
- You can add a second argument of type size_t to the declaration. You can only
- have one operator delete() or operator delete[]() for a single class.
-
- Examples of operator new() and operator delete()
-
- The result of trying to access a deleted object is undefined because the value
- of the object can change after deletion.
-
- If new and delete are called for a class object that does not declare the
- operator functions new and delete, or they are called for a nonclass object,
- the global operators new and delete are used. The global operators new and
- delete are provided in the C++ library.
-
- Note: The C++ operators for allocating and deallocating arrays of class
- objects are operator new[]() and operator delete[]().
-
- Related Information
-
- C++ new Operator
- C++ delete Operator
- Overloaded new and delete
- Debug Versions of new and delete
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of operators new() and delete() ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows two overloaded new operator functions.
-
- *
- ************************************************************************/
-
- #include <stddef.h>
- class X
- {
- public:
- void* operator new(size_t);
- void* operator new(size_t, int);
- };
-
- void main ()
- {
- X* ptr1 = new X; // calls X::operator new(sizeof(X))
- X* ptr2 = new(10) X; // calls X::operator
- // new(sizeof(X),10)
- }
-
- /************************************************************************
- *
-
- The following example shows the declaration and use of the operator functions
- operator new() and operator delete():
-
- *
- ************************************************************************/
-
- #include <stddef.h>
- class X
- {
- public:
- void* operator new(size_t);
- void operator delete(void*); // single argument
- };
- class Y
- {
- public:
- void operator delete(void*, size_t); // two arguments
- };
-
- void main ()
- {
- X* ptr = new X;
- delete ptr; // call X::operator delete(void*)
- Y* yptr;
- // ...
- delete yptr; // call Y::operator delete(void*, size_t)
- // with size of Y as second argument
- }
-
-
- ΓòÉΓòÉΓòÉ <hidden> Debug Versions of new and delete ΓòÉΓòÉΓòÉ
-
- VisualAge for C++ provides special versions of new and delete to assist you in
- debugging memory management problems. These versions can help you find where
- memory is being incorrectly allocated, written to, or freed.
-
- To enable the debug memory management functions, use the /Tm option, which also
- defines the macro __DEBUG_ALLOC__. The debug versions of new and delete, as
- well as of the C library functions (malloc and so on), are automatically called
- in place of the regular functions in your code. Do not parenthesize any calls
- to these functions, because parentheses disable the definition of the function
- name to the debug function name.
-
- To each call to new, the compiler adds 2 parameters equivalent to the current
- __FILE__ and __LINE__ macros. They are inserted as the first two parameters in
- the placement syntax. As a result, the global and class-specific versions of
- operator new change from:
-
- operator new(size_t);
- operator new(size_t , additional_parameters );
- to:
-
- operator new(size_t, const char *, size_t);
- operator new(size_t, const char *, size_t , additional_parameters );
-
- The compiler adds the same parameters to each delete call, changing all global
- and class-specific versions of delete from:
-
- operator delete(void *);
- operator delete(void * , size_t );
- to:
-
- operator delete(void *, const char *, size_t);
- operator delete(void *, const char *, size_t , size_t );
-
- The debug versions also automatically call the C library function _heap_check.
- This function checks all memory blocks allocated or freed by debug memory
- management functions to make sure that no overwriting has occurred outside the
- bounds of allocated blocks or in a free memory block. You can also call
- _heap_check explicitly.
-
- You can also call the C library function _dump_allocated to print out
- information about each memory block currently allocated by the debug memory
- management functions. Both _heap_check and _dump_allocated are only available
- when the __DEBUG_ALLOC__ macro is defined. They are described in the IBM
- VisualAge for C++ for Windows C Library Reference.
-
- All output from these functions is sent to stderr.
-
- Note: The information provided by these functions is Diagnosis, Modification,
- and Tuning information only. It is not intended to be used as a
- programming interface.
-
- You may need to include the <new.h> header file to include the prototypes of
- the debug malloc and free code that the debug versions of new and delete use.
-
- Important The changes described above take place for all occurrences of new
- and delete whether global or specific to a class. If you have provided member
- new or delete functions, you must make code changes before compiling with /Tm.
- You can use the __DEBUG_ALLOC__ macro for conditional compilation.
-
- For more information on debug memory management functions in the C library,
- see the IBM VisualAge for C++ for Windows C Library Reference.
-
-
- ΓòÉΓòÉΓòÉ 13.3. Temporary Objects ΓòÉΓòÉΓòÉ
-
- It is sometimes necessary for the compiler to create temporary objects. They
- are used during reference initialization and during evaluation of expressions
- including standard type conversions, argument passing, function returns, and
- evaluation of the throw expression.
-
- When a temporary object is created to initialize a reference variable, the name
- of the temporary object has the same scope as that of the reference variable.
- When a temporary object is created during the evaluation of an expression, it
- exists until there is a break in the flow of control of the program.
-
- If a temporary object is created for a class with constructors, the compiler
- calls the appropriate (matching) constructor to create the temporary object.
-
- When a temporary object is destroyed and a destructor exists, the compiler
- calls the destructor to destroy the temporary object. When you exit from the
- scope in which the temporary object was created, it is destroyed. If a
- reference is bound to a temporary object, the temporary object is destroyed
- when the reference passes out of scope unless it is destroyed earlier by a
- break in the flow of control. For example, a temporary object created by a
- constructor initializer for a reference member is destroyed on leaving the
- contructor.
-
- Examples of Temporary Objects
-
- Use the /Wgnr option to flag the points where temporary objects are generated.
-
- Related Information
-
- Constructors
- Destructors
- References
- Initializing References
- Expressions and Operators
- Functions
- Using Exception Handling
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Temporary Objects ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows two expressions in which temporary objects are
- constructed:
-
- *
- ************************************************************************/
-
- class Y
- {
- public:
- Y(int)={ };
- Y(Y&)={ };
- ~Y()={ };
- };
- Y add(Y y) { return y; }
-
- void main ()
- {
- Y obj1(10);
- Y obj2 = add(Y(5)); // one temporary created
- obj1 = add(obj1); // two temporaries created
- }
-
- /************************************************************************
- *
-
- In the above example, a temporary object of class type Y is created to
- construct Y(5) before it is passed to the function add(). Because obj2 is being
- constructed, the function add() can construct its return value directly into
- obj2, so another temporary object is not created. A temporary object of class
- type Y is created when obj1 is passed to the function add(). Because obj1 has
- already been constructed, the function add() constructs its return value into a
- temporary object. This second temporary object is then assigned to obj1 using
- an assignment operator.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 13.4. User-Defined Conversions ΓòÉΓòÉΓòÉ
-
- User-defined conversions allow you to specify object conversions with
- constructors or with conversion functions. User-defined conversions are
- implicitly used in addition to standard conversions for conversion of
- initializers, functions arguments, function return values, expression operands,
- expressions controlling iteration, selection statements, and explicit type
- conversions.
-
- There are two types of user-defined conversions:
-
- Conversion by constructor
- Conversion functions.
-
- Related Information
-
- Implicit Type Conversions
- Constructors and Destructors Overview
- Constructors
- C++ Classes
- Functions
-
-
- ΓòÉΓòÉΓòÉ 13.4.1. Conversion by Constructor ΓòÉΓòÉΓòÉ
-
- You can call a class constructor with a single argument to convert from the
- argument type to the type of the class.
-
- At most one user-defined conversion, either a constructor or conversion
- function, is implicitly applied to a class object. When you call a constructor
- with an argument and you have not defined a constructor accepting that argument
- type, only standard conversions are used to convert the argument to another
- argument type acceptable to a constructor for that class. No other constructors
- or conversions functions are called to convert the argument to a type
- acceptable to a constructor defined for that class.
-
- Example of Conversion by Constructor
-
- Related Information
-
- Conversion Functions
- Constructors and Destructors Overview
- Constructors
- User-Defined Conversions
- Implicit Type Conversions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Conversion by Constructor ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows conversion by constructor:
-
- *
- ************************************************************************/
-
- class Y
- {
- int a,b;
- char* name;
- public:
- Y(int i);
- Y(const char* n, int j = 0);
- };
- void add(Y);
- // ...
- void main ()
- {
- // code equivalent code
- Y obj1 = 2; // obj1 = Y(2)
- Y obj2 = "somestring"; // obj2 = Y("somestring",0)
- obj1 = 10; // obj1 = Y(10)
- add(5); // add(Y(5))
- }
-
-
- ΓòÉΓòÉΓòÉ 13.4.2. Conversion Functions ΓòÉΓòÉΓòÉ
-
- You can define a member function of a class, called a conversion function, that
- converts from the type of its class to another specified type.
-
- Syntax of a Conversion Function
-
- The conversion function specifies a conversion from the class type the
- conversion function is a member of, to the type specified by the name of the
- conversion function. Classes, enumerations, and typedef names cannot be
- declared or defined as part of the function name.
-
- Conversion functions have no arguments, and the return type is implicitly the
- conversion type. Conversion functions can be inherited. You can have virtual
- conversion functions but not static ones.
-
- Only one user-defined conversion is implicitly applied to a single value.
- User-defined conversions must be unambiguous, or they are not called.
-
- If a conversion function is declared with the keyword const, the keyword has no
- affect on the function except for acting as a tie-breaker when there is more
- than one conversion function that could be applied. Specifically, if more than
- one conversion function could be applied, all of these functions are compared.
- If any of these functions is declared with the keyword const, const is ignored
- for the purposes of this comparison. If one of these functions is a best match,
- this function is applied. If there is no best match, the functions are compared
- again, but this time const is not ignored.
-
- Example of a Conversion Function
-
- Related Information
-
- Conversion by Constructor
- Functions
- Implicit Type Conversions
- volatile and const Qualifiers
- Virtual Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Conversion Function ΓòÉΓòÉΓòÉ
-
- >>ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇoperatorΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇconversion_typeΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ(ΓöÇΓöÇ)ΓöÇΓöÇ>
- ΓööΓöÇclass::ΓöÇΓöÿ Γö£ΓöÇconstΓöÇΓöÇΓöÇΓöÇΓöñ Γö£ΓöÇ*ΓöÇΓöñ
- ΓööΓöÇvolatileΓöÇΓöÿ ΓööΓöÇ&ΓöÇΓöÿ
- >ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ{ΓöÇΓöÇfunction_bodyΓöÇΓöÇ}ΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a Conversion Function ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following code fragment shows a conversion function called operator int():
-
- *
- ************************************************************************/
-
- class Y
- {
- int b;
- public:
- operator int();
- };
- Y::operator int() {return b;}
-
- void f(Y obj )
- {
- // each value assigned is converted by Y::operator int()
- int i = int(obj);
- int j = (int)obj;
- int k = i + obj;
- }
-
-
- ΓòÉΓòÉΓòÉ 13.5. Initialization by Constructor ΓòÉΓòÉΓòÉ
-
- A class object with a constructor must be explicitly initialized or have a
- default constructor. Explicit initialization using a constructor is the only
- way, except for aggregate initialization, to initialize nonstatic constant and
- reference class members.
-
- A class object that has no constructors, no virtual functions, no private or
- protected members, and no base classes is called an aggregate. Aggregates are
- described in Structures and Unions.
-
- Class objects with constructors can be initialized with a parenthesized
- expression list. This list is used as an argument list for the call of a
- constructor that is used to initialize the class. You can also call a
- constructor with a single initialization value using the = operator. Because
- this type of expression is an initialization, not an assignment, the assignment
- operator function, if one exists, is not called. This value is used as a single
- argument for the call of a constructor. The type of the single argument must
- match the type of the first argument to the constructor. If the constructor has
- remaining arguments, these arguments must have default values.
-
- Syntax of an Explicit Initializer by Constructor
-
- Constructors can initialize their members in two different ways. A constructor
- can use the arguments passed to it to initialize member variables in the
- constructor definition:
-
- complx( double r, double i = 0.0) {re = r; im = i;}
-
- Or a constructor can have an initializer list within the definition but prior
- to the function body:
-
- complx ( double r, double i = 0) : re(r), im(i) { /* ... */ }
-
- Both methods assign the argument values to the appropriate data members of the
- class. The second method must be used to initialize base classes from within a
- derived class to initialize constant and reference members and members with
- constructors.
-
- Example of Explicit Initialization by Constructor
-
- Related Information
-
- Initializing Base Classes and Members
- Construction Order of Derived Class Objects
- Constructors and Destructors Overview
- Constructors
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of an Explicit Initializer by Constructor ΓòÉΓòÉΓòÉ
-
- The syntax for an initializer that explicitly initializes a class object with a
- constructor is:
-
- >>ΓöÇΓöÇΓö¼ΓöÇ(ΓöÇΓöÇexpressionΓöÇΓöÇ)ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇ=ΓöÇΓöÇΓö¼ΓöÇexpressionΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ
- Γöé ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇ{ΓöÇΓöÇΓöÇΓöÇexpressionΓöÇΓö┤ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ}ΓöÇΓöÿ
- ΓööΓöÇ,ΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Explicit Initialization by Constructor ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows the declaration and use of several constructors
- that explicitly initialize class objects:
-
- *
- ************************************************************************/
-
- // This example illustrates explicit initialization
- // by constructor.
-
- #include <iostream.h>
- class complx
- {
- double re, im ;
- public:
- complx(); // default constructor
- complx(const complx& c) {re = c.re; im = c.im;}
- // copy constructor
- complx( double r, double i = 0.0) {re = r; im = i;}
- // constructor with default trailing argument
- void display()
- {
- cout << "re = "<< re << " im = " << im << endl;
- }
- };
-
- void main ()
- {
- complx one(1); // initialize with complx(double, double)
- complx two = one; // initialize with a copy of one
- // using complx::complx(const complx&)
- complx three = complx(3,4); // construct complx(3,4)
- // directly into three
- complx four; // initialize with default constructor
- complx five = 5; // complx(double, double) & construct
- // directly into five
- one.display();
- two.display();
- three.display();
- four.display();
- five.display();
- }
-
- /************************************************************************
- *
-
- The above example produces the following output:
-
- re = 1 im = 0
- re = 1 im = 0
- re = 3 im = 4
- re = 0 im = 0
- re = 5 im = 0
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 13.5.1. Initializing Base Classes and Members ΓòÉΓòÉΓòÉ
-
- You can initialize immediate base classes and derived class members that are
- not inherited from base classes by specifying initializers in the constructor
- definition prior to the function body.
-
- Syntax of a Constructor Initializer
-
- In a constructor that is not inline, include the initialization list as part of
- the function definition, not as part of the class declaration.
-
- For example:
-
- class B1
- {
- int b;
- public:
- B1();
- B1(int i) : b(i) { /* ... */ } // inline constructor
- };
- class B2
- {
- int b;
- protected:
- B2();
- B2(int i); // noninline constructor
- };
- // B2 constructor definition including initialization list
- B2::B2(int i) : b(i) { /* ...*/ }
- // ...
- class D : public B1, public B2
- {
- int d1, d2;
- public:
- D(int i, int j) : B1(i+1), B2(), d1(i) {d2 = j;}
- };
-
- If you do not explicitly initialize a base class or member that has
- constructors by calling a constructor, the compiler automatically initializes
- the base class or member with a default constructor. In the above example, if
- you leave out the call B2() in the constructor of class D (as shown below), a
- constructor initializer with an empty expression list is automatically created
- to initialize B2. The constructors for class D, shown above and below, result
- in the same construction of an object of class D.
-
- class D : public B1, public B2
- {
- int d1, d2;
- public:
- // call B2() generated by compiler
- D(int i, int j) : B1(i+1), d1(i) {d2 = j;}
- };
-
- Note: You must declare base constructors with the access specifiers public or
- protected to enable a derived class to call them.
-
- Example of Base Constructors and Derivation
-
- Related Information
-
- Construction Order of Derived Class Objects
- Initialization by Constructor
- Constructors and Destructors Overview
- Constructors
- Member Access
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Constructor Initializer ΓòÉΓòÉΓòÉ
-
- The syntax for a constructor initializer is:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé
- >>ΓöÇΓöÇ:ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇidentifierΓöÇΓö¼ΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ)ΓöÇΓö┤ΓöÇΓöÇ><
- ΓööΓöÇclass_nameΓöÇΓöÿ ΓööΓöÇassignment_expressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Base Constructors and Derivation ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows how to call base constructors from derived classes:
-
- *
- ************************************************************************/
-
- class B1
- {
- int b;
- public:
- B1();
- B1(int i) : b(i) { /* ... */ }
- };
- class B2
- {
- int b;
- protected:
- B2();
- B2(int i);
- };
- B2::B2(int i) : b(i) { /* ... */ }
- class B4
- {
- public:
- B4(); // public constructor for B4
- int b;
- private:
- B4(int); // private constructor for B4
- };
- // .
- // .
- // .
-
- class D : public B1, public B2, public B4
- {
- int d1, d2;
- public:
- D(int i, int j) : B1(i+1), B2(i+2) ,
- B4(i) {d1 = i; d2 = j; }
- // error, attempt to access private constructor B4()
- };
-
- To ensure a valid call, you can change the code as follows:
-
- public:
- D(int i, int j) : B1(i+1), B2(i+2) {d1 = i; d2 = j;}
- // valid, calls public constructor for B4
-
-
- ΓòÉΓòÉΓòÉ 13.5.2. Construction Order of Derived Class Objects ΓòÉΓòÉΓòÉ
-
- When a derived class object is created using constructors, it is created in the
- following order:
-
- 1. Virtual base classes are initialized, in the order they appear in the
- base list.
- 2. Nonvirtual base classes are initialized, in declaration order.
- 3. Class members are initialized in declaration order (regardless of their
- order in the initialization list).
- 4. The body of the constructor is executed.
-
- In the following code fragment, the constructor for class B1 is called before
- the member d1 is initialized. The value passed to the constructor for class B1
- is undefined.
-
- class B1
- {
- int b;
- public:
- B1();
- B1(int i) {b = i;}
- };
- class D : public B1
- {
- int d1, d2;
- public:
- D(int i, int j) : d1(i), B1(d1) {d2 = j;}
- // d1 is not initialized in call B1::B1(d1)
- };
-
- Related Information
-
- Initializing Base Classes and Members
- Initialization by Constructor
- Constructors and Destructors Overview
- Constructors
- Derivation
-
-
- ΓòÉΓòÉΓòÉ 13.6. Copying Class Objects ΓòÉΓòÉΓòÉ
-
- You can copy one class object to another object of the same type by either
- assignment or initialization.
-
- Copy by assignment is implemented with an assignment operator function. If you
- do not define the assignment operator, it is defined as memberwise assignment.
-
- Copy by initialization is implemented with a copy constructor. If you do not
- define a copy constructor, it is defined as memberwise initialization of
- members of its class.
-
- Memberwise assignment and memberwise initialization mean that, if a class has a
- member that is a class object, the assignment operator and copy constructor of
- that class object are used to implement assignment and initialization of the
- member.
-
- Restrictions:
-
- A default assignment operator cannot be generated for a class that has:
-
- A nonstatic constant or reference data member
- A nonstatic data member or base class whose assignment operator is not
- accessible
- A nonstatic data member or base class with no assignment operator and for
- which a default assignment operator cannot be generated.
-
- A default copy constructor cannot be generated for a class that has:
-
- A nonstatic data member or base class whose copy constructor is not
- accessible
- A nonstatic data member or base class with no copy constructor and for
- which a default copy constructor cannot be generated.
-
- Related Information
-
- Copy by Assignment
- Copy by Initialization
- Constructors and Destructors Overview
- Constructors
- Overloaded Assignment
-
-
- ΓòÉΓòÉΓòÉ 13.6.1. Copy by Assignment ΓòÉΓòÉΓòÉ
-
- If you do not define an assignment operator and one is required, a default
- assignment operator is defined. If you do not define an assignment operator and
- one is not required, a default assignment operator is declared but not defined.
- If an assignment operator that takes a single argument of a class type exists
- for a class, a default assignment operator is not generated.
-
- Copy by assignment is used only in assignment.
-
- You can define an assignment operator for a class with a single argument that
- is a constant reference to that class type, only if all its base classes and
- members have assignment operators that accept constant arguments.
-
- For example:
-
- class B1
- {
- public:
- B1& operator=(const B1&);
- };
- class D: public B1
- {
- public:
- D& operator=(const D&);
- };
- D& D::operator=(const D& dobj) {D dobj2 = dobj;
- return dobj2;}
-
- Otherwise, you can define an assignment operator for a class with a single
- argument that is a reference to that class type. For example:
-
- class Z
- {
- public:
- Z& operator=( Z&);
- };
- Z& Z::operator=(Z& zobj) {Z zobj2 = zobj;
- return zobj2;}
-
- The default assignment operator for a class is a public class member. The
- return type is a reference to the class type it is a member of.
-
- Related Information
-
- Assignment Expressions
- Overloaded Assignment
- Copy by Initialization
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 13.6.2. Copy by Initialization ΓòÉΓòÉΓòÉ
-
- You can define a copy constructor for a class. If you do not define a copy
- constructor and one is required, a default copy constructor is defined. If you
- do not define a copy constructor, and one is not required, a default copy
- constructor is declared but not defined. If a class has a copy constructor
- defined, a default copy constructor is not generated.
-
- Copy by initialization is used only in initialization.
-
- You can define a copy constructor for a class with a single argument that is a
- constant reference to a class type only if all its base classes and members
- have copy constructors that accept constant arguments. For example:
-
- class B1
- {
- public:
- B1(const B1&) { /* ... */ }
- };
-
- class D: public B1
- {
- public:
- D(const D&);
- };
- D::D(const D& dobj):B1(dobj) { /* ... */ }
-
- Otherwise, you can define a copy constructor with a single reference to a class
- type argument. For example:
-
- class Z
- {
- public:
- Z(Z&);
- };
- Z::Z(Z&) { /* ...*/ }
-
- The default copy constructor for a class is a public class member.
-
- Related Information
-
- Initialization by Constructor
- Constructors
- Copy by Assignment
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 14. C++ Inheritance ΓòÉΓòÉΓòÉ
-
- In C++, you can create classes from existing classes using the object-oriented
- programming technique called inheritance. Inheritance allows you to define an
- is a relationship between classes. When members are inherited, they can be used
- as if they are members of the class that inherits them.
-
- This chapter discusses:
-
- Derivation
- Inherited Member Access
- Multiple Inheritance
- Virtual Functions
- Abstract Classes
-
- Related Information
-
- Functions
- C++ Classes
- C++ Class Members and Friends
-
-
- ΓòÉΓòÉΓòÉ 14.1. Inheritance Overview ΓòÉΓòÉΓòÉ
-
- C++ implements inheritance through the mechanism of derivation. Derivation
- allows you to reuse code by creating new classes, called derived classes, that
- inherit properties from one or more existing classes, called base classes. A
- derived class inherits the properties, including data and function members, of
- its base class. You can also add new data members and member functions to the
- derived class. You can modify the implementation of existing member functions
- or data by overriding base class member functions or data in the newly derived
- class.
-
- Multiple inheritance allows you to create a derived class that inherits
- properties from more than one base class.
-
- Because a derived class inherits members from all its base classes, ambiguities
- can result. For example, if two base classes have a member with the same name,
- the derived class cannot implicitly differentiate between the two members. Note
- that, when you are using multiple inheritance, the access to names of base
- classes may be ambiguous.
-
- Examples of Single and Multiple Inheritance
-
- Multiple inheritance allows you to have more than one base class for a single
- derived class. You can create an interconnected inheritance graph of inherited
- classes by using derived classes as base classes for other derived classes. You
- can build an inheritance graph through the process of specialization, in which
- derived classes are more specialized than their base classes. You can also work
- in the reverse direction and build an inheritance graph through generalization.
- If you have a number of related classes that share a group of properties, you
- can generalize and build a base class to embody them. The group of related
- classes becomes the derived classes of the new base class.
-
- A direct base class is a base class that appears directly as a base specifier
- in the declaration of its derived class. A direct base class is analogous to a
- parent in a hierarchical graph.
-
- An indirect base class is a base class that does not appear directly in the
- declaration of the derived class but is available to the derived class through
- one of its base classes. An indirect base class is analogous to a grandparent
- or great grandparent or great-great grandparent in a hierarchical graph. For a
- given class, all base classes that are not direct base classes are indirect
- base classes.
-
- Polymorphic functions are functions that can be applied to objects of more than
- one type. In C++, polymorphic functions are implemented in two ways:
-
- Overloaded functions are statically bound at compile time, as discussed
- in Overloading Functions.
- C++ provides virtual functions. A virtual function is a function that can
- be called for a number of different user-defined types that are related
- through derivation. Virtual functions are bound dynamically at run time.
-
- Typically, a base class has several derived classes, each requiring its own
- customized version of a particular operation. It is difficult for a base class
- to implement member functions that are useful for all of its derived classes.
- A base class would have to determine which derived class an object belonged to
- before it could execute the applicable code for that object. When a virtual
- function is called, the compiler executes the function implementation
- associated with the object that the function is called for. The implementation
- of the base class is only a default that is used when the derived class does
- not contain its own implementation.
-
- Related Information
-
- Derivation
- Multiple Inheritance
- Virtual Functions
- C++ Classes
- C++ Class Members and Friends
-
-
- ΓòÉΓòÉΓòÉ 14.1.1. Examples of Single and Multiple Inheritance ΓòÉΓòÉΓòÉ
-
- Suppose you have defined a shape class to describe and operate on geometric
- shapes. Now suppose you want to define a circle class. Because you have
- existing code that operates on the shape class, you can use inheritance to
- create the circle class. You can redefine operations in the derived circle
- class that were originally defined in the shape base class. When you manipulate
- an object of the circle class, these redefined function implementations are
- used.
-
- For example:
-
- class shape
- {
- char* name;
- int xpoint, ypoint;
- public:
- virtual void rotate(int);
- virtual void draw();
- void display() const;
- };
-
- class circle: public shape // derive class circle from
- class shape
- {
- int xorigin, yorigin;
- int radius;
- public:
- void rotate(int);
- void draw();
- void display() const;
- };
-
- In the above example, class circle inherits the data members name, xpoint and
- ypoint, as well as the member functions display(), rotate(), and draw() from
- class shape. Because the member functions rotate() and draw() are declared in
- class shape with the keyword virtual, you can provide an alternative
- implementation for them in class circle.
-
- You can also provide an alternative implementation for the nonvirtual member
- function display() in class circle. When you manipulate an argument of type
- circle using a pointer to shape, and call a virtual member function, the member
- function defined in the derived class overrides the base-class member function.
- A similar call to a nonvirtual member function will call the member function
- defined in the base class. In addition to inheriting the members of class
- shape, class circle has declared its own data members, xorigin, yorigin, and
- radius.
-
- The key difference between virtual and nonvirtual member functions is that,
- when you treat the circle class as if it were a shape, the implementations of
- the virtual functions rotate() and draw() defined in class circle are used,
- rather than those originally defined in class shape. Because display() is a
- nonvirtual member function, the original implementation of display() defined in
- class shape is used.
-
- Multiple inheritance allows you to create a derived class that inherits
- properties from more than one base class.
-
- For example, in addition to the shape class, described above, you could also
- have a symbol class. Because a circle is both a shape and a symbol, you can use
- multiple inheritance to reflect this relationship. If the circle class is
- derived from both the shape and symbol classes, the circle class inherits
- properties from both classes.
-
- class symbol
- {
- char* language;
- char letter;
- int number;
- public:
- virtual void write();
- virtual void meaning();
- };
- class shape
- {
- char* name;
- int xpoint, ypoint;
- public:
- virtual void rotate(int);
- virtual void draw();
- void display() const;
- };
- class circle: public symbol, public shape
- {
- int xorigin, yorigin;
- int radius;
- public:
- void rotate(int);
- void draw ();
- void write();
- void meaning();
- void display() const;
- };
-
- In the above example, class circle inherits the members name, xpoint, ypoint,
- display(), rotate(), and draw() from class shape and also inherits the members
- language, letter, number, write(), and meaning() from class symbol.
-
-
- ΓòÉΓòÉΓòÉ 14.2. Derivation ΓòÉΓòÉΓòÉ
-
- Inheritance is implemented in C++ through the mechanism of derivation.
- Derivation allows you to derive a class, called a derived class, from another
- class, called a base class.
-
- In the declaration of a derived class, you list the base classes of the derived
- class. The derived class inherits its members from these base classes. All
- classes that appear in the list of base classes must be previously defined
- classes.
-
- Syntax of a Derived Class
-
- Incompletely declared classes are not allowed in base lists.
-
- For example:
-
- class X; // incomplete declaration of class X
- class Y: public X // error
- {
- };
-
- When you derive a class, the derived class inherits class members of the base
- class. You can refer to inherited members (base class members) as if they were
- members of the derived class. If you redefine base class members in the derived
- class, you can still refer to the base class members by using the :: (scope
- resolution) operator.
-
- You can manipulate a derived class object as if it were a base class object.
- You can use a pointer or a reference to a derived class object in place of a
- pointer or reference to its base class. For example, you can pass a pointer or
- reference to a derived class object D to a function expecting a pointer or
- reference to the base class of D. You do not need to use an explicit cast to
- achieve this; a standard conversion is performed. You can implicitly convert a
- pointer to a derived class to point to a base class. You can also implicitly
- convert a reference to a derived class to a reference to a base class.
-
- The reverse case is not allowed. You cannot implicitly convert a pointer or a
- reference to a base class object to a pointer or reference to a derived class.
-
- Examples of Derived Classes
-
- If a member of a derived class and a member of a base class have the same name,
- the base class member is hidden in the derived class. If a member of a derived
- class has the same name as a base class, the base class name is hidden in the
- derived class. In both cases, the name of the derived class member is called
- the dominant name.
-
- Related Information
-
- Inheritance Overview
- C++ Classes
- C++ Scope Resolution Operator ::
- Multiple Inheritance
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Derived Classes ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
- You can refer to inherited members (base class members) as if they were members
- of the derived class:
-
- *
- ************************************************************************/
-
- // This example illustrates references
- // to base class members.
-
- class base
- {
- public:
- int a,b;
- };
- class derived : public base
- {
- public:
- int c;
- };
- void main()
- {
- derived d;
- d.a = 1; // base::a
- d.b = 2; // base::b
- d.c = 3; // derived::c
- }
-
- /************************************************************************
- *
-
- The derived class can also add new class members and redefine existing base
- class members. In the above example, the two inherited members, a and b, of the
- derived class d, in addition to the derived class member c, are assigned
- values.
-
- For example:
-
- *
- ************************************************************************/
-
- // This example illustrates references to base class
- // members with the scope resolution (::) operator.
-
- #include <iostream.h>
- class base
- {
- public:
- char* name;
- void display(char* i) {cout << i << endl;}
- };
- class derived : public base
- {
- public:
- char* name;
- void display(char* i){cout << i << endl;}
- };
- void main()
- {
- derived d; // create derived class object
- d.name = "Derived Class"; // assignment to derived::name
- d.base::name = "Base Class"; // assignment to base::name
-
- // call derived::display(derived::name)
- d.display(d.name);
-
- // call base::display(base::name)
- d.base::display(d.base::name);
- }
-
- /************************************************************************
- *
-
- In the following example, d, a pointer to a derived class object is assigned to
- bptr, a pointer to a base class object. A call is made to display() using bptr.
- Even though bptr has a type of pointer to base, in the body of display() the
- name member of derived is manipulated:
-
- *
- ************************************************************************/
-
- // This example illustrates how to make a pointer
- // to a derived class point to a base class.
-
- #include <iostream.h>
- class base
- {
- public:
- char* name;
- void display(char* i) {cout << i << endl;}
- };
- class derived : public base
- {
- public:
- char* name;
- void display(char* i){cout << i << endl;}
- };
- void main()
- {
- derived d;
-
- // standard conversion from derived* to base*
- base* bptr = &d;
-
- // call base::display(base::name)
- bptr->display(bptr->name);
- }
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Derived Class Declaration ΓòÉΓòÉΓòÉ
-
- The syntax for the list of base classes is:
-
- >>ΓöÇΓöÇderived_classΓöÇΓöÇ:ΓöÇΓöÇ>
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >ΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇqualified_class_specifierΓöÇΓö┤ΓöÇΓöÇ><
- Γö£ΓöÇvirtualΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé Γö£ΓöÇpublicΓöÇΓöÇΓöÇΓöÇΓöñ Γöé
- Γöé Γö£ΓöÇprivateΓöÇΓöÇΓöÇΓöñ Γöé
- Γöé ΓööΓöÇprotectedΓöÇΓöÿ Γöé
- ΓööΓöÇΓö¼ΓöÇpublicΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ
- Γö£ΓöÇprivateΓöÇΓöÇΓöÇΓöñ ΓööΓöÇvirtualΓöÇΓöÿ
- ΓööΓöÇprotectedΓöÇΓöÿ
-
- The qualified class specifier must be a class that has been previously declared
- in a class declaration as described in Class Names. The access specifiers
- (public, private, and protected) are described in Member Access.
-
- The virtual keyword can be used to declare virtual base classes.
-
- The following example shows the declaration of the derived class D and the base
- classes V, B1, and B2. The class B1 is both a base class and a derived class
- because it is derived from class V and is a base class for D.
-
- class V { /* ... */ };
- class B1 : virtual public V { /* ... */ };
- class B2 { /* ... */ };
- class D : public B1, private B2 { /* ... */ };
-
-
- ΓòÉΓòÉΓòÉ 14.3. Inherited Member Access ΓòÉΓòÉΓòÉ
-
- Access specifiers, as described in Member Access, control the level of access
- to noninherited class members. The access for an inherited member is controlled
- in three ways:
-
- When you declare a member in a base class, you can specify a level of
- access using the keywords public, private, and protected.
- When you derive a class, you can specify the access level for the base
- class in the base list.
- You can also restore the access level of inherited members. See
- Derivation Access of Base Classes for an example.
-
- Resolution of member names does not depend on the level of access associated
- with each class member.
-
- Consider the following example:
-
- class A {
- private:
- int a;
- };
- class B {
- public:
- int a;
- };
- class C : public A, public B {
- void f() { a = 0; } // ambiguous - is it A::a or B::a?
- };
-
- In this example, class A has a private member a, and class B has a public
- member a. Class C is derived from both A and B. C does not have access to
- A::a, but a in the body of f() can still resolve to either A::a or B::a. For
- this reason, a is ambiguous in the body of f().
-
- If a class is derived publicly from a base class, a protected static base
- class member can be accessed by members and friends of any classes derived
- from that base class. A protected nonstatic base class member can be accessed
- by members and friends of any classes derived from that base class by using
- one of the following:
-
- A pointer to a directly or indirectly derived class
- A reference to a directly or indirectly derived class
- An object of a directly or indirectly derived class
-
- If a class is derived privately from a base class, all protected base class
- members become private members of the derived class.
-
- Examples of Inherited Member Access Rules
-
- Related Information
-
- Derivation Access of Base Classes
- Access Declarations
- Access Resolution
- Member Access
- Derivation
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 14.3.1. Derivation Access of Base Classes ΓòÉΓòÉΓòÉ
-
- When you declare a derived class, an access specifier can precede each base
- class in the base list of the derived class. This does not alter the access
- attributes of the individual members of a base class as seen by the base class,
- but allows the derived class to restore the access attributes of the members of
- a base class.
-
- You can derive classes using any of the three access specifiers:
-
- In a public base class, public and protected members of the base class
- remain public and protected members of the derived class.
- In a private base class, public and protected members of the base class
- become private members of the derived class.
- In a protected base class, public and protected members of the base class
- are protected members of the derived class.
-
- In all cases, private members of the base class remain private. Private
- members of the base class cannot be used by the derived class unless friend
- declarations within the base class explicitly grant access to them.
-
- You can use both a structure and a class as base classes in the base list of a
- derived class declaration. If the base class is declared with the keyword
- class, its default access specifier in the base list of a derived class is
- private. If the base class is declared with the keyword struct, its default
- access specifier in the base list of a derived class is public.
-
- Examples of Public and Private Derivation
-
- Members and friends of a class can implicitly convert a pointer to an object
- of that class to a pointer to either:
-
- A direct private base class
- A protected base class (either direct or indirect)
-
- Related Information
-
- Access Declarations
- Access Resolution
- Member Access
- Derivation
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Public and Private Derivation ΓòÉΓòÉΓòÉ
-
- In the following example, class d is derived publicly from class b. Class b is
- declared a public base class by this declaration.
-
- class b
- {
- // ...
- };
- class d : public b // public derivation
- {
- // ...
- };
-
- In the following example, private derivation is used by default because no
- access specifier is used in the base list:
-
- struct bb
- {
- // ...
- };
- class dd : bb // private derivation
- {
- // ...
- };
-
-
- ΓòÉΓòÉΓòÉ 14.3.2. Access Declarations ΓòÉΓòÉΓòÉ
-
- You can restore access to members of a base class using an access declaration.
- It allows you to change the access of a public member of a private or protected
- base class back to public. You can also change the access of a protected member
- of a private base class back to protected. Access is adjusted by using the base
- class member qualified name in the public or protected declarations of the
- derived class.
-
- You only use access declarations to restore base class access. You cannot
- change the access to a member to give it more access than it was originally
- declared with. You cannot change the access of a private member to public or to
- protected. You cannot change the access of a protected member to public.
-
- An access declaration cannot be used to restrict access to a member that is
- accessible in a base class.
-
- It is redundant to use an access declaration to change the access to a public
- member of a public base class to public, or to change the access to a protected
- member of a protected base class to protected.
-
- Examples of Access Declarations
-
- Access declarations can only be used to adjust the access of a member of a base
- class. The base class that an access declaration appears in can be directly or
- indirectly inherited by the derived class.
-
- You cannot adjust the access to a base class member if a member with the same
- name exists in a class derived from that base class.
-
- If you use an access declaration to adjust the access to an overloaded
- function, the access is adjusted for all functions with that name in the base
- class.
-
- Related Information
-
- Derivation Access of Base Classes
- Access Resolution
- Member Access
- Derivation
- Overloading Functions
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Access Declarations ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, the member b of the base class base is declared
- public in its base class declaration. Class derived is derived privately from
- class base. The access declaration in the public section of class derived
- restores the access level of the member b back to public.
-
- *
- ************************************************************************/
-
- // This example illustrates using access declarations
- // to restore base class access.
-
- #include <iostream.h>
- class base
- {
- char a;
- public:
- char c, b;
- void bprint();
- };
-
- class derived: private base
- {
- char d;
- public:
- char e;
- base::b; // restore access to b in derived
- void dprint();
- derived(char ch) { base::b = ch; }
- };
-
- void print(derived& d)
- {
- cout << " Here is d " << d.b << endl;
- }
-
- void main()
- {
- derived obj('c');
- print(obj);
- }
-
- /************************************************************************
- *
-
- The external function print(derived&) can use the member b of base because the
- access of b has been restored to public. The external function print(derived&)
- can also use the members e and dprint() because they are declared with the
- keyword public in the derived class. The derived class member dprint() can use
- the members of its own class, d and e, in addition to the inherited members, b,
- c, and bprint(), that are declared with the keyword public in the base class.
- The base class member bprint() can use all the members of its own class, a, b,
- and c.
-
- You can also use an access declaration in a nested class. For example:
-
- class B
- {
- public:
- class N // nested class
- {
- public:
- int i; // public member
- };
- };
- class D: private B::N // derive privately
- {
- public:
- B::N::i; // restores access to public
- };
-
- You cannot convert a pointer to a derived class object to a pointer to a base
- class object if the base class is private or protected. For example:
-
- class B { /* ... */ };
- class D : private B { /* ... */ }; // private base class
-
- void main ()
- {
- D d;
- B* ptr;
- ptr = &d; // error
- }
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 14.3.3. Access Resolution ΓòÉΓòÉΓòÉ
-
- Access resolution is the process by which the accessibility of a particular
- class member is determined. Accessibility is dependent on the context. For
- example, a class member can be accessible in a member function but inaccessible
- at file scope. The following describes the access resolution procedure used by
- the compiler.
-
- In general, two scopes must be established before access resolution is applied.
- These scopes reduce an expression or declaration into a simplified construct to
- which the access rules are applied. Access rules are described in Member
- Access. These scopes are:
-
- Call scope The scope that encloses the expression or declaration that
- uses the class member.
-
- Reference scope The scope that identifies the class.
-
- For example, in the following code:
-
- // This example illustrates access resolution.
-
- class B { public: int member; }; // declaration
- class A : B {} // declaration
- void main()
- {
- A aobject; // declaration
- aobject.member = 10; // expression
- }
-
- the reference scope for member is the type of aobject, that is class type A.
-
- Reference scope is chosen by simplifying the expression (or declaration)
- containing the member. An expression can be thought of as being reduced to a
- simple expression of the form obj.member where obj is the reference scope.
- Reference scope is selected as follows:
-
- If the member is qualified with . (dot) or -> (arrow), the reference
- scope is the type of the object that is immediately to the left of the .
- or -> operator closest to the member. Unqualified members are treated as
- if they are qualified with this->.
-
- If the member is a type member or a static member and is qualified with
- :: (the scope resolution operator), the reference scope is the type
- immediately to the left of the :: operator closest to the member.
-
- Otherwise, the reference scope is the call scope.
-
- The call scope and the reference scope determine the accessibility of a class
- member. Once these scopes are resolved, the effective access of the member is
- determined. Effective access is the access of the member as it is seen from
- the reference scope. It is determined by taking the original access of the
- member in its scope as the effective access and changing it as the class
- hierarchy is traversed from the member's class to the reference scope.
- Effective access is altered as the class hierarchy is traversed for each
- derivation by the following:
-
- The derivation access of a base class (see Derivation Access of Base
- Classes)
- Access declarations that are applied to the members (see Access
- Declarations)
- Friendships that are granted to the call scope (see Member Access)
-
- After effective access is determined for a member, the access rules are
- applied as if the effective access were the original access of the member. A
- member is only accessible if the access rules say that it is.
-
- Example of Access Resolution
-
- Related Information
-
- Derivation Access of Base Classes
- Access Declarations
- Member Access
- Derivation
- Overloading Functions
- C++ Scope Resolution Operator ::
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Access Resolution ΓòÉΓòÉΓòÉ
-
- The following example demonstrates the access resolution procedure.
-
- class A
- {
- public:
- int a;
- };
- class B : private A
- {
- friend void f (B*);
- };
- void f(B* b)
- {
- b->a = 10; // is 'a' accessible to f(B*) ?
- }
- // ...
-
- The following steps occur to determine the accessibility of A::a in f(B*):
-
- 1. The call scope and reference scope of the expression b->a are determined:
-
- a. The call scope is the function f(B*).
- b. The reference scope is class B.
-
- 2. The effective access of member a is determined:
-
- a. Because the original access of the member a is public in class A,
- the initial effective access of a is public.
- b. Because B inherits from A privately, the effective access of a
- inside class B is private.
- c. Because class B is the reference scope, the effective access
- procedure stops here. The effective access of a is private.
-
- 3. The access rules are applied. The rules state that a private member can
- be accessed by a friend or a member of the member's class. Because f(B*)
- is a friend of class B, f(B*) can access the private member a.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Inherited Member Access Rules ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example demonstrates inherited member access rules.
-
- *
- ************************************************************************/
-
- // This example illustrates inherited member access rules.
-
- class B
- {
- int a;
- public:
- int b,c;
- void f(int) {}
- protected:
- int d;
- void g(int) {}
- };
-
- class D1 : public B
- {
- int a;
- public:
- int b;
- void h(int i )
- {
- g(i); // valid, protected B::g(int)
- B::b = 10; // valid, B::b (not local b)
- d = 5 ; // valid, protected B::d
- }
- };
-
- class D2 : private B
- {
- int e;
- public:
- B::c; // modify access to B::c
- void h(int i) { d = 5; } // valid,protected B::d
- };
-
- void main( )
- {
-
- int i= 1; // declare and initialize local variable
- D1 d1; // create object of class d1
- D2 d2; // create object of class d2
-
- d1.a = 5; // error, D1::a is private in class D1
- d2.b = 10; // error, B::b is inherited private to
- // derived class D2
- d2.c = 5; // valid, modified access from private to public
- d2.B::c = 5; // valid, public B::c
- d1.c = 5; // valid, B::c is inherited publicly
- d1.d = 5; // error, B::d is protected in base class
- d2.e = 10; // error, private D2::e
- d1.g(i); // error, g(int) is protected in base class
- d1.h(i); // valid
- d2.h(i); // valid
- }
-
- /************************************************************************
- *
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 14.4. Multiple Inheritance ΓòÉΓòÉΓòÉ
-
- You can derive a class from more than one base class. Deriving a class from
- more than one direct base class is called multiple inheritance.
-
- In the following example, classes A, B, and C are direct base classes for the
- derived class X:
-
- class A { /* ... */ };
- class B { /* ... */ };
- class C { /* ... */ };
- class X : public A, private B, public C { /* ... */ };
-
- The order of derivation is relevant only to determine the order of default
- initialization by constructors and cleanup by destructors. For more
- information, see Initialization by Constructor.
-
- A direct base class cannot appear in the base list of a derived class more than
- once:
-
- class B1 { /* ... */ }; // direct base class
- class D : public B1, private B1 { /* ... */ }; // error
-
- However, a derived class can inherit an indirect base class more than once, as
- shown in the following example:
-
- class L { /* ... */ }; // indirect base class
- class B2 : public L { /* ... */ };
- class B3 : public L { /* ... */ };
- class D : public B2, public B3 { /* ... */ }; // valid
-
- In the above example, class D inherits the indirect base class L once through
- class B2 and once through class B3. However, this may lead to ambiguities
- because two objects of class L exist, and both are accessible through class D.
- You can avoid this ambiguity by referring to class L using a qualified class
- name, for example, B2::L or B3::L .
-
- You can also avoid this ambiguity by using the base specifier virtual to
- declare a base class.
-
- Examples of Single and Multiple Inheritance
-
- Related Information
-
- Virtual Base Classes
- Multiple Access
- Inheritance Overview
- Derivation
- Initialization by Constructor
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 14.4.1. Virtual Base Classes ΓòÉΓòÉΓòÉ
-
- If you have an inheritance graph in which two or more derived classes have a
- common base class, you can use a virtual base class to ensure that the two
- classes share a single instance of the base class.
-
- In the following example, an object of class D has two distinct objects of
- class L, one through class B1 and another through class B2. You can use the
- keyword virtual in front of the base class specifiers in the base lists of
- classes B1 and B2 to indicate that only one class L, shared by class B1 and
- class B2, exists.
-
- For example:
-
- class L { /* ... */ }; // indirect base class
- class B1 : virtual public L { /* ... */ };
- class B2 : virtual public L { /* ... */ };
- class D : public B1, public B2 { /* ... */ }; // valid
-
- Using the keyword virtual in this example ensures that an object of class D
- inherits only one object of class L.
-
- A derived class can have both virtual and nonvirtual base classes. For example:
-
- class V { /* ... */ };
- class B1 : virtual public V { /* ... */ };
- class B2 : virtual public V { /* ... */ };
- class B3 : public V { /* ... */ };
- class D : public B1, public B2, public B3 { /* ... */
- };
-
- In the above example, class D has two objects of class V, one that is shared by
- classes B1 and B2 and one through class B3.
-
- Related Information
-
- Multiple Inheritance
- Multiple Access
- Inheritance Overview
- Derivation
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ 14.4.2. Multiple Access ΓòÉΓòÉΓòÉ
-
- In an inheritance graph containing virtual base classes, a name that can be
- reached through more than one path is accessed through the path that gives the
- most access.
-
- For example:
-
- class L { public: void f(); };
- class B1 : private virtual L { /* ... */ };
- class B2 : public virtual L { /* ... */ };
- class D : public B1, public B2
- {
- public:
- void f() {L::f();} // L::f() is accessed through B2
- // and is public
- };
-
- In the above example, the function f() is accessed through class B2. Because
- class B2 is inherited publicly and class B1 is inherited privately, class B2
- offers more access.
-
- An accessible base class is a publicly derived base class that is neither
- hidden nor ambiguous in the inheritance hierarchy.
-
- When you derive classes, ambiguities can result if base and derived classes
- have members with the same names. Access to a base class member is ambiguous if
- you use a name or qualified name that does not refer to a unique function,
- object, type, or enumerator. The declaration of a member with an ambiguous name
- in a derived class is not an error. The ambiguity is only flagged as an error
- if you use the ambiguous member name.
-
- For example, if two base classes have a member of the same name, an attempt to
- access the member by the derived class is ambiguous. You can resolve ambiguity
- by qualifying a member with its class name using the :: (scope resolution)
- operator.
-
- Example of Resolving Ambiguous Access
-
- The compiler checks for ambiguities at compile time. Because ambiguity checking
- occurs before access control or type checking, ambiguities may result even if
- only one of several members with the same name is accessible from the derived
- class.
-
- Conversions (either implicit or explicit) from a derived class pointer or
- reference to a base class pointer or reference must refer unambiguously to the
- same accessible base class object. For example:
-
- class W { /* ... */ };
- class X : public W { /* ... */ };
- class Y : public W { /* ... */ };
- class Z : public X, public Y { /* ... */ };
- void main ()
- {
- Z z;
- X* xptr = &z; // valid
- Y* yptr = &z; // valid
- W* wptr = &z; // error, ambiguous reference to class W
- // X's W or Y's W ?
- }
-
- You can use virtual base classes to avoid ambiguous reference. For example:
-
- class W { /* ... */ };
- class X : public virtual W { /* ... */ };
- class Y : public virtual W { /* ... */ };
- class Z : public X, public Y { /* ... */ };
- void main ()
- {
- Z z;
- X* xptr = &z; // valid
- Y* yptr = &z; // valid
- W* wptr = &z; // valid, W is virtual therefore only one
- // W subobject exists
- }
-
- Related Information
-
- Virtual Base Classes
- Multiple Inheritance
- C++ Scope Resolution Operator ::
- Inheritance Overview
- Derivation
- Member Access
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Resolving Ambiguous Access ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example uses the :: (scope resolution) operator to resolve an
- ambiguous reference.
-
- *
- ************************************************************************/
-
- // This example illustrates ambiguous base classes.
-
- class B1
- {
- public:
- int i;
- int j;
- int g( );
- };
- class B2
- {
- public:
- int j;
- int g( );
- };
- // ...
- class D : public B1, public B2
- {
- public:
- int i;
- };
- void main ()
- {
- D dobj;
- D *dptr = &dobj;
- dptr -> i = 5; // valid, D::i
- dptr -> j = 10; // error, ambiguous reference to j
- dptr->B1::j = 10; // valid, B1::j
- dobj.g( ); // error, ambiguous reference to g( )
- dobj.B2::g( ); // valid, B2::g( )
- }
-
-
- ΓòÉΓòÉΓòÉ 14.5. Virtual Functions ΓòÉΓòÉΓòÉ
-
- In C++, dynamic binding is supported by the mechanism of virtual functions.
- Virtual functions must be members of a class. Use virtual functions when you
- expect a class to be used as a base class in a derivation and when the
- implementation of the function may be overridden in the derived class. You can
- declare a member function with the keyword virtual in its class declaration.
- For example:
-
- class B
- {
- int a,b,c;
- public:
- virtual int f();
- };
-
- You can reimplement a virtual member function, like any member function, in any
- derived class. The implementation that is executed when you make a call to a
- virtual function depends on the type of the object for which it is called. If a
- virtual member function is called for a derived class object and the function
- is redefined in the derived class, the definition in the derived class is
- executed. In this case, the redefined derived class function is said to
- override the base class function. This occurs even if the access to the
- function is through a pointer or reference to the base class.
-
- If you call a virtual function with a pointer that has base class type but
- points to a derived class object, the member function of the derived class is
- called. However, if you call a nonvirtual function with a pointer that has base
- class type, the member function of the base class is called regardless of
- whether the pointer points to a derived class object.
-
- Example of Overriding Virtual Functions
-
- If the argument types or the number of arguments of the two functions are
- different, the functions are considered different, and the function in the
- derived class does not override the function in the base class. The function in
- the derived class hides the function in the base class.
-
- The return type of an overriding virtual function can differ from the return
- type of the overridden virtual function provided that:
-
- The overridden function returns a pointer or a reference to a class T
-
- AND
-
- The overriding virtual function returns a pointer or a reference to a
- class derived from T.
-
- An error does result when a virtual function that returns D* overrides a
- virtual function that returns B* where B is an ambiguous base class of D. The
- reason is that two or more instances of class B will exist within class D, and
- the compiler will not know which base B to return. For more information, see
- Function Return Values.
-
- A virtual function cannot be global or static because, by definition, a
- virtual function is a member function of a base class and relies on a specific
- object to determine which implementation of the function is called. You can
- declare a virtual function to be a friend of another class.
-
- If a function is declared virtual in its base class, it can still be accessed
- directly using the :: (scope resolution) operator. In this case, the virtual
- function call mechanism is suppressed and the function implementation defined
- in the base class is used. In addition, if you do not redefine a virtual
- member function in a derived class, a call to that function uses the function
- implementation defined in the base class.
-
- A virtual function must be one of the following:
-
- Defined
- Declared pure
- Defined and declared pure
-
- A base class containing one or more pure virtual member functions is called an
- abstract class.
-
- Related Information
-
- Virtual Base Classes
- Ambiguous Virtual Function Calls
- Virtual Function Access
- Abstract Classes
- Function Return Values
- Friends
- C++ Scope Resolution Operator ::
- Inheritance Overview
- Derivation
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Overriding Virtual Functions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows how virtual functions can be redefined.
-
- *
- ************************************************************************/
-
- class B
- {
- public:
- virtual int f();
- virtual int g();
- int h();
- };
- class D : public B
- {
- public:
- int f();
- int g(char*); // hides B::g()
- int h();
- };
- // ...
- void main ()
- {
- D d;
- B* bptr = &d;
-
- bptr->f(); // calls D::f() because f() is virtual
- bptr->h(); // calls B::h() because h() is nonvirtual
- bptr->g(); // calls B::g()
- d.g(); // error, wrong number and type of arguments
- d.g("string"); // calls D::g(char*)
- }
-
-
- ΓòÉΓòÉΓòÉ 14.5.1. Ambiguous Virtual Function Calls ΓòÉΓòÉΓòÉ
-
- It is an error to override one virtual function with two or more ambiguous
- virtual functions. This can happen in a derived class that inherits from two
- nonvirtual bases that are derived from a virtual base class.
-
- Example of Ambiguous Virtual Functions
-
- A special case occurs when the ambiguous overriding virtual functions come from
- separate instances of the same class type. In the following example, there are
- two objects (instances) of class L. There are two data members L::count, one in
- class A and one in class B. If the declaration of class D is allowed,
- incrementing L::count in a call to L::f() with a pointer to class V is
- ambiguous.
-
- class V
- {
- public:
- virtual void f();
- };
- class L : virtual public V
- {
- int count;
- void f();
- };
- void L::f() {++count;}
- class A : public L
- { /* ... */ };
- class B : public L
- { /* ... */ };
- class D : public A, public B { /* ... */ }; // error
- void main ()
- {
- D d;
- V* vptr = &d;
- vptr->f();
- }
-
- In the above example, the function L::f() is expecting a pointer to an L
- object; that is, the this pointer for class L, as its first implicit argument.
- Because there are two objects of class L in a D object, there are two this
- pointers that could be passed to L::f(). Because the compiler cannot decide
- which this pointer to pass to L::f(), the declaration of class D is flagged as
- an error.
-
- Related Information
-
- Virtual Functions
- Virtual Function Access
- Multiple Access
- C++ Scope Resolution Operator ::
- Member Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Ambiguous Virtual Functions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows a class that inherits from two nonvirtual bases
- that are derived from a virtual base class.
-
- *
- ************************************************************************/
-
- class V
- {
- public:
- virtual void f() { /* ... */ };
- };
- class A : virtual public V
- {
- void f() { /* ... */ };
- };
- class B : virtual public V
- {
- void f() { /* ... */ };
- };
- class D : public B, public A { /* ... */ }; // error
- void main ()
- {
- D d;
- V* vptr = &d;
- vptr->f(); // which f(), A::f() or B::f()?
- }
-
- /************************************************************************
- *
-
- In class A, only A::f() will override V::f(). Similarly, in class B, only
- B::f() will override V::f(). However, in class D, both A::f() and B::f() will
- try to override V::f(). This attempt is not allowed because it is not possible
- to decide which function to call if a D object is referenced with a pointer to
- class V, as shown in the above example. Because only one function can override
- a virtual function, the compiler flags this situation as an error.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 14.5.2. Virtual Function Access ΓòÉΓòÉΓòÉ
-
- The access for a virtual function is specified when it is declared. The access
- rules for a virtual function are not affected by the access rules for the
- function that later overrides the virtual function. In general, the access of
- the overriding member function is not known.
-
- If a virtual function is called with a pointer or reference to a class object,
- the type of the class object is not used to determine the access of the virtual
- function. Instead, the type of the pointer or reference to the class object is
- used.
-
- In the following example, when the function f() is called using a pointer
- having type B*, bptr is used to determine the access to the function f().
- Although the definition of f() defined in class D is executed, the access of
- the member function f() in class B is used. When the function f() is called
- using a pointer having type D*, dptr is used to determine the access to the
- function f(). This call produces an error because f() is declared private in
- class D.
-
- class B
- {
- public:
- virtual void f();
- };
- class D : public B
- {
- private:
- void f();
- };
- void main ()
- {
- D dobj;
- B *bptr = &dobj;
- D *dptr = &dobj;
- bptr->f(); // valid, virtual B::f() is public,
- // D::f() is called
- dptr->f(); // error, D::f() is private
- }
-
- Related Information
-
- Virtual Functions
- Ambiguous Virtual Function Calls
- Inherited Member Access
-
-
- ΓòÉΓòÉΓòÉ 14.6. Abstract Classes ΓòÉΓòÉΓòÉ
-
- An abstract class is a class that is designed to be specifically used as a base
- class. An abstract class contains at least one pure virtual function. Pure
- virtual functions are inherited. You can declare a function to be pure by using
- a pure specifier in the declaration of the member function in the class
- declaration.
-
- For example:
-
- class AB // abstract class
- {
- public:
- virtual void f()= 0; // pure virtual member function
- };
-
- A function that is declared pure typically has no definition and cannot be
- executed. Attempting to call a pure virtual function that has no implementation
- is undefined; however, such a call does not cause an error. No objects of an
- abstract class can be created.
-
- Note: Because destructors are not inherited, a virtual destructor that is
- declared pure must have a definition.
-
- Virtual member functions are inherited. If a base class contains a pure virtual
- member function and a class derived from that base class does not redefine that
- pure virtual member function, the derived class itself is an abstract class.
- Any attempt to create an object of the derived class type produces an error.
-
- Examples of Errors using Abstract Classes
-
- You cannot use an abstract class as the type of an explicit conversion, as an
- argument type, or as the return type for a function. You can declare a pointer
- or reference to an abstract class.
-
- Related Information
-
- Virtual Functions
- Inheritance Overview
- Derivation
- C++ Classes
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Errors using Abstract Classes ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows an attempt to create an object of an abstract class
- type.
-
- *
- ************************************************************************/
-
- class AB // abstract class
- {
- public:
- virtual void f()= 0; // pure virtual member function
- };
- class D: public AB
- {
- public:
- void f();
- };
- // ...
- void main ()
- {
- D d;
- d.f() ; // calls D::f()
- AB ab; // error, cannot create an object of an
- // abstract class type
- }
-
- /************************************************************************
- *
-
- The following example shows an attempt to create an object of a class derived
- from an abstract class, but that does not redefine the pure virtual function of
- that abstract class.
-
- *
- ************************************************************************/
-
- For example:
-
- class AB // abstract class
- {
- public:
- virtual void f()= 0; // pure virtual member function
- };
- class D2: public AB
- {
- int a,b,c;
- public:
- void g();
- };
- // ...
- void main ()
- {
- D2 d;
- // error, cannot declare an object of abstract class D2
- }
-
- To avoid the error in the above example, provide a declaration of D2::f().
-
-
- ΓòÉΓòÉΓòÉ 14.7. Classes for Runtime Type Identification ΓòÉΓòÉΓòÉ
-
- To use the typeid operator in Runtime Type Identification (RTTI) you must
- include the C++ standard header <typeinfo.h> This header defines the following
- classes:
-
- type_info Describes the RTTI available to the implementation; it defines the
- object returned by the typeid operator. It is a polymorphic type
- that supplies comparison and collation operators and provides a
- member function that returns the name of the type represented.
-
- The copy constructor and the assignment operator for the class
- type_info are private; objects of this type cannot be copied.
-
- bad_cast Defines the type of objects thrown as exceptions to report dynamic
- cast expressions that have failed.
-
- bad_typeid Defines the type of objects thrown as exceptions to report a null
- pointer in a typeid expression.
-
- VisualAge for C++ also defines the extended_type_info class, which provides
- support for implementing operations for a persistent object store. It is
- described in the IBM VisualAge for C++ for Windows Programming Guide.
-
- Related Information
-
- dynamic_cast<>()
- typeid()
- Inheritance Overview
- Virtual Functions
- Unary Expressions
-
-
- ΓòÉΓòÉΓòÉ 15. C++ Templates ΓòÉΓòÉΓòÉ
-
- This chapter describes the C++ template facility. A template specifies how an
- individual class, function, or static data member can be constructed by
- providing a blueprint description of classes or functions within the template.
-
- Unlike an ordinary class or function definition, a template definition contains
- the template keyword, and uses a type argument, instead of a type, in one or
- more of the constructs used to define the class or function template.
- Individual classes or functions can then be generated simply by specifying the
- template name and by naming the type for the particular class or function as
- the type argument of the template. You can use templates to define a family of
- types or functions.
-
- This chapter discusses:
-
- Template Syntax
- Structuring Your Program Using Templates
- Class Templates
- Function Templates
- Differences between Class and Function Templates
- Member Function Templates
- Friends and Templates
- Static Data Members and Templates
-
- Note: C++ objects with templates can now be linked as a separate step with
- the VisualAge for C++ linker command.
-
- Related Information
-
- Functions
- C++ Classes
- Type Specifiers
- define
- implementation
-
- See the IBM VisualAge for C++ for Windows Programming Guide for programming
- hints on using templates in C++ programs.
-
-
- ΓòÉΓòÉΓòÉ 15.1. Template Syntax ΓòÉΓòÉΓòÉ
-
- The syntax for a template is:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- >>ΓöÇΓöÇtemplateΓöÇΓöÇΓöÉΓöÇΓöÇΓö┤Γö¼ΓöÇargument-declarationΓöÇΓö¼Γö┤ΓöÇΓöÇ>ΓöÇΓöÇ><
- Γöé Γöé Γöé
- ΓööΓöÇtypeΓöÇΓöÇidentifierΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The declaration in a template declaration must define or declare one of the
- following:
-
- A class
- A function
- A static member of a template class
-
- The identifier of a type is defined to be a type_name in the scope of the
- template declaration. A template declaration can appear as a global
- declaration only.
-
- The template arguments (within the < and > delimitiers) specify the types and
- the constants within the template that must be specified when the template is
- instantiated.
-
- Examples of Templates
-
- Default intializers are permitted in template arguments, under the following
- conditions:
-
- They can only be applied to nontype template arguments.
- Like functions, they can only be applied to trailing arguments.
- Subsequent template declarations can add default initializers but cannot
- redefine existing default initializers.
- They can only be applied to class template declarations, not to function
- template declarations.
-
- Note: A template that defines a member function of a class template is
- treated as a function template. Such a template cannot have default
- intializers.
-
- Example of Default Initializers in Templates
-
- Related Information
-
- Structuring Your Program Using Templates
- Class Templates
- Function Templates
- C++ Classes
- Functions
- Static Members
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Templates ΓòÉΓòÉΓòÉ
-
- Given the following template:
-
- template<class L> class Key
- {
- L k;
- L* kptr;
- int length;
- public:
- Key(L);
- // ...
- };
-
- The following table shows what the classes Key<int>, Key<char*>, and
- Key<mytype> look like:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé class Key<int> i; Γöé class Key<char*> c; Γöé class Key<mytype> m; Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé class Key<int> { Γöé class Key<char*> { Γöé class Key<mytype> { Γöé
- Γöé int k; Γöé char* k; Γöé mytype k; Γöé
- Γöé int * kptr; Γöé char** kptr; Γöé mytype* kptr; Γöé
- Γöé int length; Γöé int length; Γöé int length; Γöé
- Γöé public: Γöé public: Γöé public: Γöé
- Γöé Key(int); Γöé Key(char*); Γöé Key(mytype); Γöé
- Γöé // ... }; Γöé // ... }; Γöé // ... }; Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- The declarations create the following objects:
-
- i of type Key<int>
- c of type Key<char*>
- m of type Key<mytype>
-
- Note that these three classes have different names. The types contained within
- the angle braces are not arguments to the class names, but part of the class
- names themselves. Key<int> and Key<char*> are class names. Within the context
- of the example, a class called Key (with no template argument list) is
- undefined.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Default Initializers in Templates ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows a valid template declaration with default
- initializers:
-
- *
- ************************************************************************/
-
- // This example shows a template declaration
- // with default initializers.
-
- #include <stdio.h>
-
- template <class T, int i=1> class X
- {
- public:
- T s;
- X(int j=4);
- int val(T&)
- {
- return i;
- };
- };
-
- template <class T, int i> X<T,i>::X(int j):s(i){
- printf("i=%d j=%d\n",i,j);
- }
-
- void main()
- {
- X<int> myX(2);
- X<int,3> myX2(4);
- }
-
-
- ΓòÉΓòÉΓòÉ 15.2. Structuring Your Program Using Templates ΓòÉΓòÉΓòÉ
-
- You can structure your program three ways using templates:
-
- 1. Include the function template definition (both the .h and .c files) in
- all files that may reference the corresponding template functions.
-
- 2. Include the function template declaration (the .h file only) in all files
- that may reference the corresponding template functions, but include the
- function definition (both the .h and .c files) in one file only.
-
- 3. Include the declaration of the function templates in a header file and
- the definition in a source file that has the same name. When you include
- the header file in your source, the compiler automatically generates the
- template functions. Use the /Ft+ option to enable this method.
-
- The following examples use two files to illustrate all three methods: stack.h
- and stackdef.h
-
- To instantiate a stack of 50 ints, you would declare the following in each
- source file that requires it:
-
- stack<int> intStack(50);
-
- For method 1, each source file using the template should include both stack.h
- and stackdef.h.
-
- For method 2, every source file should include stack.h, but only one of the
- files needs to include stackdef.h.
-
- For method 3, every source file should include stack.h. The compiler
- automatically generates the template functions in the TEMPINC subdirectory
- that is created in the current directory. To use this method, copy stackdef.h
- to stack.c and use the /Ft+ option, which is the default.
-
- Note: C++ objects with templates can now be linked as a separate step with
- the VisualAge for C++ linker command.
-
- Related Information
-
- Template Syntax
- Class Templates
- Function Templates
- Differences between Class and Function Templates
- "Using Templates in C++ Programs" in the IBM VisualAge for C++ for
- Windows Programming Guide.
-
-
- ΓòÉΓòÉΓòÉ <hidden> stack.h and stackdef.h ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- stack.h
-
- *
- ************************************************************************/
-
- #ifndef _STACK_TPL_H
- #define _STACK_TPL_H
-
- template<class T>
- class stack
- {
- private:
- T* v;
- T* p;
- int sz;
-
- public:
- stack( int );
- ~stack();
- void push( T );
- };
- #endif
-
- /************************************************************************
- *
-
- stackdef.h
-
- *
- ************************************************************************/
-
- #include "stack.h"
-
- template<class T> stack<T>::stack( int s )
- {
- v = p = new T[sz=s];
- }
-
- template<class T> stack<T>::~stack()
- {
- delete [] v;
- }
-
- template<class T> void stack<T>::push( T a )
- {
- *p++ = a;
- }
-
-
- ΓòÉΓòÉΓòÉ 15.3. Class Templates ΓòÉΓòÉΓòÉ
-
- The relationship between a class template and an individual class is like the
- relationship between a class and an individual object. An individual class
- defines how a group of objects can be constructed, while a class template
- defines how a group of classes can be generated.
-
- Note the distinction between the terms class template and template class:
-
- Class template is a template used to generate template classes. A class
- template can be only a declaration, or it can be a
- definition of the class.
-
- Template class is an instance of a class template.
-
- A template definition is identical to any valid class definition that the
- template might generate, except for the following:
-
- The class template definition is preceded by template <
- template-argument-list > where template-argument-list can include zero
- or more arguments of user-defined type and zero or more argument
- declarations. The template-argument-list must contain at least one
- argument.
-
- Types, variables, constants and objects within the class template can be
- declared with arguments of user-defined type as well as with explicit
- types (for example, int or char).
-
- The template-argument-list can include argument-declarations (for
- example, int a or char* b), which are generally used to define constant
- values within the created class.
-
- A class template can declare a class without defining it by using an
- elaborated type specifier. For example:
-
- template <class L,class T> class key;
-
- This reserves the name as a class template name. All template declarations for
- a class template must have the same types and number of template arguments.
- Only one template declaration containing the class definition is allowed.
-
- You can instantiate the class template by declaring a template class. If the
- definitions of the member functions of the template class are not inlined,
- then you have to define them. When you instantiate a template class, its
- argument list must match the argument list in the class template declaration.
-
- Syntax of a Template Class Instantiation
-
- Note: When you have nested template argument lists, you must have a
- separating space between the > at the end of the inner list and the one at the
- end of the outer list. Otherwise, there is an ambiguity between the output
- operator >> and two template list delimiters >.
-
- template <class L,class T> class key
- {
- // ...
- };
- template <class L> class vector
- {
- // ...
- };
-
- void main ()
- {
- class key <int, vector<int> >; // instantiate template
- }
-
- Objects and functions of individual template classes can be accessed by any of
- the techniques used to access ordinary class member objects and functions.
-
- Examples of Accessing Class Template Members
-
- Related Information
-
- Class Template Declarations and Definitions
- Nontype Template Arguments
- Explicitly Defined Template Classes
- Function Templates
- Template Syntax
- Structuring Your Program Using Templates
- C++ Classes
- Differences between Class and Function Templates
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of a Template Class Instantiation ΓòÉΓòÉΓòÉ
-
- The syntax for instantiation of a template class is:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- >>ΓöÇΓöÇtemplate-nameΓöÇΓöÇΓöÉΓöÇΓöÇΓö┤Γö¼ΓöÇtypeΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ>ΓöÇΓöÇ><
- Γöé Γöé Γöé
- ΓööΓöÇassignment-expressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Accessing Class Template Members ΓòÉΓòÉΓòÉ
-
- Given a class template:
-
- template<class T> class vehicle
- {
- public:
- vehicle() { /* ... */ } // constructor
- ~vehicle() {}; // destructor
- T kind[16];
- T* drive();
- static void roadmap();
- // ...
- };
-
- and the declaration:
-
- vehicle<char> bicycle; // instantiates the template
-
- the constructor, the constructed object, and the member function drive() can be
- accessed with any of the following (assuming the standard header file
- <string.h> is included in the program file):
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé constructor Γöé "vehicle<char> bicycle; Γöé
- Γöé Γöé // constructor called automatically Γöé
- Γöé Γöé // object bicycle created" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé object "bicycle" Γöé "strcpy (bicycle.kind, "10 speed"); Γöé
- Γöé Γöé bicycle.kind[0] = '2';" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé function "drive()" Γöé "char* n = bicycle.drive();" Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé function "roadmap()" Γöé "vehicle<char>::roadmap();" Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ 15.3.1. Class Template Declarations and Definitions ΓòÉΓòÉΓòÉ
-
- A class template must be declared before any declaration of a corresponding
- template class. A class template definition can only appear once in any single
- compilation unit. A class template must be defined before any use of a template
- class that requires the size of the class or refers to members of the class.
-
- In the following example, the class template key is declared before it is
- defined. The declaration of the pointer keyiptr is valid because the size of
- the class is not needed. The declaration of keyi, however, causes an error.
-
- template <class L> class key; // class template declared,
- // not defined yet
- //
- class key<int> *keyiptr; // declaration of pointer
- //
- class key<int> keyi; // error, cannot declare keyi
- // without knowing size
- //
- template <class L> class key // now class template defined
- {
- // ...
- };
-
- If a template class is used before the corresponding class template is defined,
- the compiler issues an error. A class name with the appearance of a template
- class name is considered to be a template class. In other words, angle brackets
- are valid in a class name only if that class is a template class.
-
- The definition of a class template is not compiled until the definition of a
- template class is required. At that point, the class template definition is
- compiled using the argument list of the template class to instantiate the
- template arguments. Any errors in the class definition are flagged at this
- time. If the definition of a class template is never required, it is not
- compiled. In this case, some errors in the definition might not be flagged by
- the compiler. The /Wcls option can be used to find errors in class templates
- that are not compiled.
-
- A class template can only be defined once within a compilation unit, and the
- class template name cannot be declared to refer to any other template, class,
- object, function, value, or type in the same scope.
-
- Related Information
-
- Class Templates
- Nontype Template Arguments
- Explicitly Defined Template Classes
- /Wcls option
- C++ Classes
- Function Templates
- Differences between Class and Function Templates
-
-
- ΓòÉΓòÉΓòÉ 15.3.2. Nontype Template Arguments ΓòÉΓòÉΓòÉ
-
- A nontype template argument provided within a template argument list is an
- expression whose value can be determined at compile time. Such arguments must
- be constant expressions, addresses of functions or objects with external
- linkage, or addresses of static class members. Nontype template arguments are
- normally used to initialize a class or to specify the sizes of class members.
-
- For nontype integral arguments, the instance argument matches the corresponding
- template argument as long as the instance argument has a value and sign
- appropriate to the argument type.
-
- For nontype address arguments, the type of the instance argument must be of the
- form identifier or &identifier, and the type of the instance argument must
- match the template argument exactly, except that a function name is changed to
- a pointer to function type before matching.
-
- The resulting values of nontype template arguments within a template argument
- list form part of the template class's type. If two template class names have
- the same template name and if their arguments have identical values, they are
- the same class.
-
- Example of Nontype Template Arguments
-
- Note: Arguments that contain the < symbol or the > symbol must be enclosed in
- parentheses to prevent it from being parsed as a template argument list
- delimiter when it is being used as a relational operator or a nested
- template delimiter. For example, the arguments in the following
- definition are valid:
-
- myfilebuf<double, (20>10)> x; // valid
-
- The following definition, however, is not valid because the greater than
- operator (>) is interpreted as the closing delimiter of the template argument
- list:
-
- myfilebuf<double, 20>10> x; // error
-
- If the template arguments do not evaluate identically, the objects created are
- of different types:
-
- myfilebuf<double,200> x; // create object x of class
- // myfilebuf<double,200>
- myfilebuf<double,200.0> y; // error, 200.0 is a double,
- // not an int
-
- The instantiation of y fails because the value 200.0 is of type double, and
- the template argument is of type int.
-
- The following two objects:
-
- myfilebuf<double, 128> x
- myfilebuf<double, 512> y
-
- belong to separate template classes, and referencing either of these objects
- later with myfilebuf<double> is an error.
-
- A class template does not need to have a type argument if it has nontype
- arguments. For example, the following template is a valid class template:
-
- template<int i> class C
- {
- public:
- int k;
- C() { k = i; }
- };
-
- This class template can be instantiated by declarations such as:
-
- class C<100>;
- class C<200>;
-
- Again, these two declarations refer to distinct classes because the values of
- their nontype arguments differ.
-
- Related Information
-
- Class Templates
- Class Template Declarations and Definitions
- Explicitly Defined Template Classes
- C++ Classes
- Function Templates
- Differences between Class and Function Templates
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Nontype Template Arguments ΓòÉΓòÉΓòÉ
-
- In the following example, a class template is defined that requires a nontype
- template int argument as well as the type argument:
-
- template<class T, int size> class myfilebuf
- {
- T* filepos;
- static int array[size];
- public:
- myfilebuf() { /* ... */ }
- ~myfilebuf();
- advance(); // function defined elsewhere in program
- };
-
- In this example, the template argument size becomes a part of the template
- class name. An object of such a template class is created with both the type
- arguments of the class and the values of any additional template arguments.
-
- An object x, and its corresponding template class with arguments double and
- size=200, can be created from this template with a value as its second template
- argument:
-
- myfilebuf<double,200> x;
-
- x can also be created using an arithmetic expression:
-
- myfilebuf<double,10*20> x;
-
- The objects created by these expressions are identical because the template
- arguments evaluate identically. The value 200 in the first expression could
- have been represented by an expression whose result at compile time is known to
- be equal to 200, as shown in the second construction.
-
-
- ΓòÉΓòÉΓòÉ 15.3.3. Explicitly Defined Template Classes ΓòÉΓòÉΓòÉ
-
- You can override the definition of a class template of a particular template
- class by providing a class definition for the type of class required. For
- example, the following class template creates a class for each type for which
- it is referenced, but that class may be inappropriate for a particular type:
-
- template<class M> class portfolio
- {
- double capital;
- M arr;
- // ...
- } ;
-
- The type for which the template class is inappropriate can be defined by using
- the applicable template class name. Assuming the inappropriately defined type
- is stocks, you can redefine the class portfolio<stocks> as follows:
-
- class portfolio<stocks>
- {
- double capital;
- stocks yield;
- // ...
- };
-
- An explicit specialization of a template class can be defined before the class
- template is declared. In particular, a template class such as portfolio<stocks>
- can be defined before its class template has been defined.
-
- Related Information
-
- Class Templates
- Class Template Declarations and Definitions
- Nontype Template Arguments
- C++ Classes
- Function Templates
- Differences between Class and Function Templates
-
-
- ΓòÉΓòÉΓòÉ 15.4. Function Templates ΓòÉΓòÉΓòÉ
-
- A function template allows you to define a group of functions that are the same
- except for the types of one or more of their arguments or objects. All type
- arguments in a function template must be used in the argument list or in the
- class qualifier for the function name. The type of a template function argument
- need not be explicitly specified when the template function is called. In this
- respect, a template function differs from a template class.
-
- Note the distinction between the terms function template and template function:
-
- Function template is a template used to generate template functions. A
- function template can be only a declaration, or it can
- define the function.
-
- Template function is a function generated by a function template.
-
- Example of a Function Template
-
- Because template functions can be generated in all compilation units that
- contain function template definitions, you may want to group function template
- definitions into one or two compilation units. Using templates in C++ programs
- is described completely in the IBM VisualAge for C++ for Windows Programming
- Guide.
-
- Related Information
-
- Overloading Resolution for Template Functions
- Explicitly Defined Template Functions
- Function Template Declarations and Definitions
- Differences between Class and Function Templates
- Functions
- Class Templates
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of a Function Template ΓòÉΓòÉΓòÉ
-
- If you want to create a function approximate(), which determines whether two
- values are within 5% of each other, you can define the following template:
-
- #include <math.h>
- template <class T> int approximate (T first, T second)
- {
- double aptemp=double(first)/double(second);
- return int(abs(aptemp-1.0) <= .05);
- };
-
- Assuming you have two values of type float you want to compare, you can use the
- approximate function template:
-
- float a=3.24, b=3.35;
- if (approximate(a,b))
- cout << "a and b are pretty close" << endl;
-
- A template function int approximate(float,float) is generated to resolve the
- call.
-
-
- ΓòÉΓòÉΓòÉ 15.4.1. Overloading Resolution for Template Functions ΓòÉΓòÉΓòÉ
-
- Resolution of overloaded template functions is done in the following order:
-
- 1. Look for a function with an exact type match. This does not include
- template functions, unless such functions were explicitly declared using
- a function declaration. Trivial conversions are performed if they produce
- an exact type match.
-
- 2. Look for a function template that allows generation of a function with an
- exact type match. Trivial conversions are performed if they produce an
- exact type match.
-
- 3. Try ordinary overloading resolution for functions already present. This
- does not include template functions, unless such functions were
- explicitly declared using a function declaration.
-
- A call to a template function causes an error, and no overloading is done if
- the following conditions are true:
-
- The only available functions for a call are template functions.
- These functions would require nontrivial conversions for the call to
- succeed.
- These functions have not been explicitly declared.
-
- Example of Overloading a Template Function
-
- Related Information
-
- Trivial Conversions
- Implicit Type Conversions
- Function Templates
- Explicitly Defined Template Functions
- Function Template Declarations and Definitions
- Functions
- Differences between Class and Function Templates
- Class Templates
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Overloading a Template Function ΓòÉΓòÉΓòÉ
-
- In the case of the approximate() function template:
-
- #include <math.h>
- template <class T> int approximate (T first, T second)
- {
- double aptemp=double(first)/double(second);
- return int(abs(aptemp-1.0) <= .05);
- };
-
- if the two input values are of different types, overloading resolution does not
- take place:
-
- float a=3.24;
- double b=3.35;
- if (approximate(a,b)) // error, different types
- { /* ... */ }
-
- The solution is to force a conversion to one of the available function types by
- explicitly declaring the function for the chosen type. To resolve the
- float/double example, include the following function declaration:
-
- int approximate(double a, double b);
- // force conversion of the float to double
-
- This declaration creates a function approximate() that expects two arguments of
- type double, so that when approximate(a,b) is called, the overloading is
- resolved by converting variable a to type double.
-
-
- ΓòÉΓòÉΓòÉ 15.4.2. Explicitly Defined Template Functions ΓòÉΓòÉΓòÉ
-
- In some situations, a function template can define a group of functions in
- which, for one function type, the function definition would be inappropriate.
- For instance, the function template:
-
- template<class T> int approximate(T first, T second);
-
- determines whether two values are within 5% of each other. The algorithm used
- for this function template is appropriate for numerical values, but for char*
- values, it would indicate whether the pointers to two character strings are
- within 5% of one another, not whether the strings themselves are approximately
- equal. Whether two pointers are within 5% of each other is not useful
- information. You can define an explicit template function for char* values to
- compare the two strings themselves, character by character.
-
- Example of an Explicitly Defined Template Function
-
- Explicit definition has the same effect on template overloading resolution as
- explicit declaration (See Overloading Resolution for Template Functions for
- more information.) If a template function is explicitly defined for:
-
- int approximate(double a, double b) { /* ... */ }
-
- then a call of:
-
- double a=3.54;
- float b=3.5;
- approximate(a,b);
-
- resolves in a call to approximate(double a, double b) and variable b is
- converted to type double.
-
- Related Information
-
- Function Templates
- Overloading Resolution for Template Functions
- Function Template Declarations and Definitions
- Functions
- Differences between Class and Function Templates
- Class Templates
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of an Explicitly Defined Template Function ΓòÉΓòÉΓòÉ
-
- The following explicitly defined template function compares two strings and
- returns a value indicating whether more than 5% of the characters differ
- between the two strings:
-
- #include <string.h>
- int approximate(char *first, char *second)
- {
- if (strcmp(first,second) == 0)
- return 1; // strings are identical
-
- double difct=0;
- int maxlen=0;
-
- if (strlen(first)>strlen(second))
- maxlen=strlen(first);
-
- else maxlen=strlen(second);
- for (int i=0; i<=maxlen ; ++i)
- if ( first[i] != second[i] ) difct++;
- return int((difct / maxlen) <= .05 );
- }
-
- Given this definition, the function call: approximate("String A","String B");
- invokes the explicitly defined function above, and no template function is
- generated.
-
-
- ΓòÉΓòÉΓòÉ 15.4.3. Function Template Declarations and Definitions ΓòÉΓòÉΓòÉ
-
- When a template function is defined explicitly within a compilation unit, this
- definition is used in preference to any instantiation from the function
- template. For example, if one compilation unit contains the code:
-
- #include <iostream.h>
- template <class T> T f(T i) {return i+1;}
- void main()
- {
- cout << f(2) << endl;
- }
-
- and another contains:
-
- int f(int i) {return i+2;}
-
- when compiled and run, the program prints the number 4 to standard output,
- indicating that the explicitly defined function was used to resolve the call to
- f().
-
- Each template, whether of a class or of a function, must be defined at most
- once within a compilation unit. The same applies to an explicitly defined
- template class or function. Function templates and class templates can be
- declared many times.
-
- A template class is considered declared if its name is used. A template
- function is considered declared if any of the following applies:
-
- A function whose name matches a function template's name is declared, and
- an appropriate template function can be generated.
- A function whose name matches a function template's name is called, and
- an appropriate template function can be generated.
- A function whose name matches a function template's name is called, and
- the template function has been explicitly defined.
- The address of a template function is taken in such a way that
- instantiation can occur. This means the pointer to function must supply a
- return type and argument types that can be used to instantiate the
- template function.
-
- A template function is instantiated or generated if the function is referenced
- in any of the following ways, provided that function is not explicitly defined
- elsewhere in the program:
-
- The function is declared.
- A call to the function is made.
- The address of the function is taken.
-
- When a template function is instantiated, the body of the function template is
- compiled using the template argument list of the template class to instantiate
- the template arguments. Any errors in the function definition are flagged at
- this time. If a template function is never generated from a function template,
- it is not compiled. In this case, some errors in the function definition might
- not be flagged by the compiler.
-
- Related Information
-
- Function Templates
- Overloading Resolution for Template Functions
- Explicitly Defined Template Functions
- Functions
- Differences between Class and Function Templates
- Class Templates
-
-
- ΓòÉΓòÉΓòÉ 15.5. Differences between Class and Function Templates ΓòÉΓòÉΓòÉ
-
- The name of a template class is a compound name consisting of the template name
- and the full template argument list enclosed in angle braces. Any references to
- a template class must use this complete name. For example:
-
- template <class T, int range> class ex
- {
- T a;
- int r;
- // ...
- };
- //...
- ex<double,20> obj1; // valid
- ex<double> obj2; // error
- ex obj3; // error
-
- C++ requires this explicit naming convention to ensure that the appropriate
- class can be generated.
-
- A template function, on the other hand, has the name of its function template
- and the particular function chosen to resolve a given template function call is
- determined by the type of the calling arguments. In the following example, the
- call min(a,b) is effectively a call to min(int a, int b), and the call min(af,
- bf) is effectively a call to min(float a, float b):
-
- // This example illustrates a template function.
-
- template<class T> T min(T a, T b)
- {
- if (a < b)
- return a;
- else
- return b;
- }
- void main()
- {
- int a = 0;
- int b = 2;
- float af = 3.1;
- float bf = 2.9;
- cout << "Here is the smaller int " << min(a,b) << endl;
- cout << "Here is the smaller float " << min(af, bf) << endl;
- }
-
- Related Information
-
- Class Templates
- Function Templates
- C++ Classes
- Functions
-
-
- ΓòÉΓòÉΓòÉ 15.6. Member Function Templates ΓòÉΓòÉΓòÉ
-
- In Function Templates, a function template was defined outside of any template
- class. However, functions in C++ are often member functions of a class. If you
- want to create a class template and a set of function templates to go with that
- class template, you do not have to create the function templates explicitly, as
- long as the function definitions are contained within the class template. Any
- member function (inlined or noninlined) declared within a class template is
- implicitly a function template. When a template class is declared, it
- implicitly generates template functions for each function defined in the class
- template.
-
- You can define template member functions three ways:
-
- 1. Explicitly at file scope for each type used to instantiate the template
- class.
- 2. At file scope with the template arguments.
- 3. Inlined in the class template itself.
-
- Examples of Defining Template Member Functions
-
- Member function templates are used to instantiate any functions that are not
- explicitly generated. If you have both a member function template and an
- explicit definition, the explicit definition is used.
-
- The template argument is not used in a constructor name. For example:
-
- template<class L> class Key
- {
- Key(); // default constructor
- Key( L ); // constructor taking L by value
- Key<L>( L ); // error, <L> implicit within class template
- };
-
- The declaration Key<L>(L) is an error because the constructor does not use the
- template argument. Assuming this class template was corrected by removing the
- offending line, you can define a function template for the class template's
- constructor:
-
- // Constructor contained in function template:
- template<class L>
- Key<L>::Key(int) { /* ... */ }
- // valid, constructor template argument assumed template<class L>
-
- Key<L>::Key<L>(int) { /* ... */ }
- /* error, constructor template argument <L> implicit
- in class template argument */
-
- A template function name does not include the template argument. The template
- argument does, however, appear in the template class name if a member function
- of a template class is defined or declared outside of the class template. The
- definition: Key<L>::Key(int) { /* ... */ } is valid because Key<L> (with
- template argument) refers to the class, while Key(int) { /* ... */ } refers to
- the member function.
-
- Related Information
-
- Class Templates
- Function Templates
- C++ Class Members and Friends
-
-
- ΓòÉΓòÉΓòÉ <hidden> Examples of Defining Template Member Functions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following three examples illustrate the three ways to define template
- member functions:
-
- Method 1
-
- *
- ************************************************************************/
-
- template <class T> class key
- {
- public:
- void f(T);
- };
- void key<char>::f(char) { /* ... */ }
- void key<int>::f(int ) { /* ... */ }
-
- void main()
- {
- int i = 9;
- key< int> keyobj;
- keyobj.f(i);
- }
-
- /************************************************************************
- *
-
- Method 2
-
- *
- ************************************************************************/
-
- template <class T> class key
- {
- public:
- void f(T);
- };
- template <class T> void key <T>::f(T) { /* ... */ }
-
- void main()
- {
- int i = 9;
- key< int> keyobj;
- keyobj.f(i);
- }
-
- /************************************************************************
- *
-
- Method 3
-
- *
- ************************************************************************/
-
- template <class T> class key
- {
- public:
- void f(T) { /* ... */ }
- };
-
- void main()
- {
- int i = 9;
- key< int> keyobj;
- keyobj.f(i);
- }
-
-
- ΓòÉΓòÉΓòÉ 15.7. Friends and Templates ΓòÉΓòÉΓòÉ
-
- A friend function can be declared in a class template either as a single
- function shared by all classes created by the template or as a template
- function that varies from class to class within the class template. For
- example:
-
- template<class T> class portfolio
- {
- //...
- friend void taxes();
- friend void transact(T);
- friend portfolio<T>* invest(portfolio<T>*);
- friend portfolio* divest(portfolio*); //error
- // ...
- };
-
- In this example, each declaration has the following characteristics:
-
- taxes()
- is a single function that can access private and protected members of any
- template class generated by the class template. Note that taxes() is not a
- template function.
-
- transact(T)
- is a function template that declares a distinct function for each class
- generated by the class template. The only private and protected members
- that can be accessed by functions generated from this template are the
- private and protected members of their template class.
-
- invest(portfolio<T>*)
- is a function template whose return and argument types are pointers to
- objects of type portfolio<T>. Each class generated by the class template
- will have a friend function of this name, and each such function will have
- a pointer to an object of its own class as both its return type and its
- argument type.
-
- divest(portfolio*)
- is an error because portfolio* attempts to point to a class template. A
- pointer to a class template is undefined and produces an error. This
- statement can be corrected by using the syntax of the invest() function
- template instead.
-
- Because all friend functions in this example are declared but not defined, you
- could create a set of function templates to define those functions that are
- implicitly template functions (that is, all the valid functions except
- taxes()). The function templates would then be used to instantiate the
- template functions as required.
-
- Related Information
-
- Friends
- Class Templates
- Function Templates
- C++ Classes
- Functions
-
-
- ΓòÉΓòÉΓòÉ 15.8. Static Data Members and Templates ΓòÉΓòÉΓòÉ
-
- A static declaration within a class template declares a static data member for
- each template class generated from the template. The static declaration can be
- of template argument type or of any defined type.
-
- Like member function templates, you can explicitly define a static data member
- of a template class at file scope for each type used to instantiate a template
- class. For example:
-
- template <class T> class key
- {
- public:
- static T x;
- };
- int key<int>::x;
- char key<char>::x;
- void main()
- {
- key<int>::x = 0;
- }
-
- You can also define a static data member of a template class using a template
- definition at file scope. For example:
-
- template <class T> class key
- {
- public:
- static T x;
- };
- template <class T> T key<T> ::x; // template definition
- void main()
- {
- key<int>::x = 0;
- }
-
- When you instantiate a template class, you must have either an explicit
- definition or a template definition for each static data member, but not both.
-
- Example of Static Data Members in Templates
-
- Related Information
-
- Static Members
- Class Templates
- Explicitly Defined Template Classes
- Function Templates
- Explicitly Defined Template Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Static Data Members in Templates ΓòÉΓòÉΓòÉ
-
- In the following example:
-
- template<class L> class Key
- {
- static L k;
- static L* kptr;
- static int length;
- // ...
- }
-
- The definitions of static variables and objects must be instantiated at file
- scope. If the classes Key<int> and Key<double> are instantiated from this
- template, and no template definitions exist, the following static data members
- must be explicitly defined at file scope, or an error occurs:
-
- int Key<int>::k, Key<int>::length, Key<double>::length;
- int* Key<int>::kptr;
- double Key<double>::k;
- double* Key<double>::kptr = 0;
-
-
- ΓòÉΓòÉΓòÉ 16. C++ Exception Handling ΓòÉΓòÉΓòÉ
-
- This chapter describes the VisualAge for C++ implementation of C++ exception
- handling. It discusses:
-
- Formal and Informal Exception Handling
- Using Exception Handling
- Transferring Control
- Constructors and Destructors in Exception Handling
- Exception Specifications
- unexpected() and terminate() Functions
-
- Note: C++ exception handling is not the same as Windows exception handling. A
- C++ exception exists only within the C++ language. Windows exceptions
- are generated by the operating system, and can be used by the VisualAge
- for C++ library to generate a signal. In this section, the term
- exception refers to a C++ exception.
-
- Windows exception handling is described in detail in the IBM VisualAge for C++
- for Windows Programming Guide.
-
-
- ΓòÉΓòÉΓòÉ 16.1. C++ Exception Handling Overview ΓòÉΓòÉΓòÉ
-
- Exception handling provides a way for a function that encounters an unusual
- situation to throw an exception and pass control to a direct or indirect caller
- of that function. The caller may or may not be able to handle the exception.
- Code that intercepts an exception is called a handler. Regardless of whether or
- not the caller can handle an exception, it may rethrow the exception so it can
- be intercepted by another handler.
-
- C++ provides three language constructs to implement exception handling:
-
- Try blocks
- Catch blocks
- Throw expressions
-
- Within a function, any unusual situation can be flagged with a throw
- expression. The throw expression is of type void. Your program can throw an
- object to pass information back to the caller. Any object can be thrown,
- including the object that caused the exception or an object constructed when
- the exception occurred.
-
- A throw expression, or a call to a function that may throw an exception,
- should be enclosed within a try block. If the called function throws an
- exception and an exception handler is defined to catch the type of the object
- thrown, the exception handler is executed. In C++, a catch block implements an
- exception handler. A try block must be accompanied by one or more catch
- clauses, otherwise the compiler will flag it as an error.
-
- A catch block follows immediately after a try statement or immediately after
- another catch block. A catch block includes a parenthesized exception
- declaration containing optional qualifiers, a type, and an optional variable
- name. The declaration specifies the type of object that the exception handler
- may catch. Once an exception is caught, the body of the catch block is
- executed. If no handler catches an exception, the program is terminated.
-
- Exception handling is not strictly synonymous with error handling, because the
- implementation allows the passing of an exception whether or not an error
- actually occurred. You can use exception handlers for things other than
- handling errors. For example, you can transfer control back to the original
- caller of a function. You might use this if you wanted to process the Quit key
- in a program and transfer control back to the driver program when the user
- types Quit. To do this exception handlers could be used to throw an object
- back to the driver.
-
- Note: C++ exception handling is not the same as Windows exception handling. A
- C++ exception exists only within the C++ language. Windows exceptions
- are generated by the operating system, and can be used by the VisualAge
- for C++ library to generate a signal. In this section, the term
- exception refers to a C++ exception.
-
- Windows exception handling is described in detail in the IBM VisualAge for C++
- for Windows Programming Guide.
-
- Related Information
-
- Formal and Informal Exception Handling
- Using Exception Handling
- Transferring Control
-
-
- ΓòÉΓòÉΓòÉ 16.2. Formal and Informal Exception Handling ΓòÉΓòÉΓòÉ
-
- While the exception handling features of C++ offer a formal mechanism for
- handling exceptions (language implemented), in many situations informal
- exception handling (logic implemented) is more appropriate. Generally speaking,
- formal exception handling should be implemented in libraries, classes, and
- functions likely to be accessed by several programs or programmers. It should
- also be used in classes and functions that are repeatedly accessed within a
- program but are not well-suited to handling their exceptions themselves.
- Because formal exception handling is designed for exceptional circumstances, it
- is not guaranteed to be efficient. Program performance is usually not affected
- when you do not invoke formal exception handling, although it can inhibit some
- optimizations.
-
- Informal exception handling, in which an appropriate action is defined if an
- error or exception occurs, is often more suitable for handling errors. For
- example, a simple error, such as entering incorrect input, can more easily and
- clearly be handled by testing the input for validity and by requesting the
- input again if the original input is incorrect.
-
- Related Information
-
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
-
-
- ΓòÉΓòÉΓòÉ 16.3. Using Exception Handling ΓòÉΓòÉΓòÉ
-
- The three keywords designed for exception handling in C++ are try, catch, and
- throw.
-
- Syntax of Exception Handling Keywords
-
- The steps required to implement an exception handler are:
-
- 1. Functions that are expected to be used by many programs are coded so
- that, when an error is detected, an exception is thrown. The throw
- expression generally throws an object. It may be created explicitly for
- purposes of exception handling, or it may be the object that caused the
- error to be detected. An example of throwing the problem object:
-
- .
- .
- .
- int input=0;
- cout << "Enter a number between 1 and 10:";
- cin >> input;
-
- if (input < 1 || input >> 10);
- throw(input); //throw the actual problem object
- .
- .
- .
-
- The following is an example of throwing an object for the purpose of
- exception handling:
-
- .
- .
- .
- int input=0;
- cout << "Enter a number between 1 and 10:";
- cin >> input;
-
- if (input < 1 || input >> 10)
- throw(out_of_range_object); //throw object to tell handler
- //what happened
-
- 2. Exceptions are anticipated in a caller by means of a try statement.
- Function calls that you anticipate might produce an exception must be
- enclosed in braces and preceded by the keyword try.
-
- 3. Immediately following the try block, you must code one or more catch
- blocks. Each catch block identifies what type or class of objects it can
- catch:
-
- a. If the object thrown matches the type of a catch expression, control
- passes to that catch block.
- b. If the object thrown does not match the first catch block,
- subsequent catch blocks are searched for a matching type.
- c. If no match is found, the search continues in all enclosing try
- blocks and then in the code that called the current function.
- d. If no match is found after all try blocks are searched, a call to
- terminate() is made. For information on the default handlers of
- uncaught exceptions, see unexpected() and terminate() Functions.
-
- Notes:
-
- Any object can be thrown if it can be copied and destroyed in the
- function from which the throw occurs.
- Exceptions should never be thrown from a C language signal handler. The
- result is undefined, and can cause program termination.
-
- A catch argument causes an error if it is a value argument, and a copy of it
- cannot be generated. Similarly, a throw expression causes an error if a copy
- of the value of the expression being thrown cannot be generated.
-
- Example of an Incorrect catch Argument
-
- Related Information
-
- C++ Exception Handling Overview
- Formal and Informal Exception Handling
- Transferring Control
- Exception Specifications
- unexpected() and terminate() Functions
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of Exception Handling Keywords ΓòÉΓòÉΓòÉ
-
- The syntax for the try and catch keywords is:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇtryΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇstatementΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓöÇcatchΓöÇΓöÇ(ΓöÇΓöÇ>
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >ΓöÇΓöÇΓö¼ΓöÇ. . .ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ)ΓöÇΓöÇ{ΓöÇΓöÇΓöÇΓöÇstatementΓöÇΓö┤ΓöÇΓöÇ}ΓöÇΓöÇ><
- Γöé ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ Γöé
- Γöé Γöé Γöé
- ΓööΓöÇΓöÇΓöÇtype_specifierΓöÇΓö┤ΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÿ
- Γö£ΓöÇdeclaratorΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- ΓööΓöÇabstract_declaratorΓöÇΓöÿ
-
- The syntax for the throw keyword is:
-
- >>ΓöÇΓöÇthrowΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇ><
- ΓööΓöÇassignment_expressionΓöÇΓöÿ
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of an Incorrect catch Argument ΓòÉΓòÉΓòÉ
-
- A catch argument causes an error if it is a value argument, and a copy of it
- cannot be generated. For example:
-
- class B {
- public:
- B();
- B(B&);
- };
- // the following catch block will cause an error
- //
- catch(const B x)
- {
- // ...
- }
-
- The catch block causes an error because the compiler does not know the type of
- the object thrown at compile time. It assumes that the type of the thrown
- object is the same as the type of the catch argument. In the above example, the
- thrown object is assumed to be of type const B. The compiler uses a copy
- constructor on the thrown argument to create the catch argument. Because there
- is no copy constructor for class B that accepts const B as an input argument,
- the compiler cannot perform the construction and an error occurs.
-
-
- ΓòÉΓòÉΓòÉ 16.4. Transferring Control ΓòÉΓòÉΓòÉ
-
- C++ implements the termination model of exception handling. In the termination
- model, when an exception is thrown, control never returns to the throw point.
- The throw point is the point in program execution where the exception occurred.
-
- C++ exception handling does not implement the resumption model of exception
- handling, which allows an exception handler to correct the exception and then
- return to the throw point.
-
- When an exception is thrown, control is passed out of the throw expression and
- out of the try block that anticipated the exception. Control is passed to the
- catch block whose exception type matches the object thrown. The catch block
- handles the exception as appropriate. If the catch block ends normally, the
- flow of control passes over all subsequent catch blocks.
-
- When an exception is not thrown from within a try block, the flow of control
- continues normally through the block, and passes over all catch blocks
- following the try block.
-
- An exception handler cannot return control to the source of the error by using
- the return statement. A return issued in this context returns from the function
- containing the catch block.
-
- If an exception is thrown and no try block is active, or if a try block is
- active and no catch block exception declaration matches the object thrown, a
- call to terminate() is issued. A call to terminate() in turn calls abort() to
- terminate the program. The abort() C library function is defined in the
- standard header file <stdlib.h>.
-
- Example of Basic Exception Handling
-
- Related Information
-
- Catching Exceptions
- Nested Try Blocks
- Rethrowing an Exception
- Using a Conditional Expression in a Throw Expression
- C++ Exception Handling Overview
- Using Exception Handling
- Exception Specifications
- unexpected() and terminate() Functions
- abort - Stop a Program
- return
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Basic Exception Handling ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example illustrates the basic use of try, catch, and throw. The
- program prompts for numerical input and determines the input's reciprocal.
- Before it attempts to print the reciprocal to standard output, it checks that
- the input value is nonzero, to avoid a division by zero. If the input is zero,
- an exception is thrown, and the catch block catches the exception. If the input
- is nonzero, the reciprocal is printed to standard output.
-
- *
- ************************************************************************/
-
- // This example illustrates the basic use of
- // try, catch, and throw.
-
- #include <iostream.h>
- #include <stdlib.h>
- class IsZero { /* ... */ };
- void ZeroCheck( int i )
- {
- if (i==0)
- throw IsZero();
- }
- void main()
- {
- double a;
-
- cout << "Enter a number: ";
- cin >> a;
- try
- {
- ZeroCheck( a );
- cout << "Reciprocal is " << 1.0/a << endl;
- }
- catch ( IsZero )
- {
- cout << "Zero input is not valid" << endl;
- exit(1);
- }
- exit(0);
- }
-
- /************************************************************************
- *
-
- This example could have been coded more efficiently by using informal exception
- handling. However, it provides a simple illustration of formal exception
- handling.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 16.4.1. Catching Exceptions ΓòÉΓòÉΓòÉ
-
- You can declare a handler to catch many types of exceptions. The allowable
- objects that a function can catch are declared in the parentheses following the
- catch keyword (the catch argument). You can catch objects of the fundamental
- types, base and derived class objects, references, and pointers to all of these
- types. You can also catch const and volatile types.
-
- You can also use the catch(...) form of the handler to catch all thrown
- exceptions that have not been caught by a previous catch block. The ellipsis in
- the catch argument indicates that any exception thrown can be handled by this
- handler.
-
- If an exception is caught by a catch(...) block, there is no direct way to
- access the object thrown. Information about an exception caught by catch(...)
- is very limited. You can declare an optional variable name if you want to
- access the thrown object in the catch block.
-
- A catch block can only catch accessible objects. The object caught must have an
- accessible copy constructor. For more information on access, see Member Access;
- on copy constructors, see Copy by Initialization.
-
- An argument in the catch argument of a handler matches an argument in the
- expression of the throw expression (throw argument) if any of the following
- conditions is met:
-
- The catch argument type matches the type of the thrown object.
- The catch argument is a public base class of the thrown class object.
- The catch specifies a pointer type, and the thrown object is a pointer
- type that can be converted to the pointer type of the catch argument by
- standard pointer conversion. Pointer conversion is described on page
- Pointer Conversions.
-
- Note: If the type of the thrown object is const or volatile, the catch
- argument must also be a const or volatile for a match to occur. However, a
- const, volatile, or reference type catch argument can match a nonconstant,
- nonvolatile, or nonreference object type. A nonreference catch argument type
- matches a reference to an object of the same type.
-
- Always place a catch block that catches a derived class before a catch block
- that catches the base class of that derived class (following a try block). If
- a catch block for objects of a base class is followed by a catch block for
- objects of a derived class of that base class, the latter block is flagged as
- an error.
-
- A catch block of the form catch(...) must be the last catch block following a
- try block or an error occurs. This placement ensures that the catch(...) block
- does not prevent more specific catch blocks from catching exceptions intended
- for them.
-
- Related Information
-
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
- Exception Specifications
- volatile and const Qualifiers
- Nested Try Blocks
- Rethrowing an Exception
-
-
- ΓòÉΓòÉΓòÉ 16.4.2. Nested Try Blocks ΓòÉΓòÉΓòÉ
-
- When try blocks are nested and a throw occurs in a function called by an inner
- try block, control is transferred outward through the nested try blocks until
- the first catch block is found whose argument matches the argument of the throw
- expression.
-
- For example:
-
- try
- {
- func1();
- try
- {
- func2();
- }
- catch (spec_err) { /* ... */ }
- func3();
- }
- catch (type_err) { /* ... */ }
- // if no throw is issued, control resumes here.
-
- In the above example, if spec_err is thrown within the inner try block (in this
- case, from func2()), the exception is caught by the inner catch block, and,
- assuming this catch block does not transfer control, func3() is called. If
- spec_err is thrown after the inner try block (for instance, by func3()), it is
- not caught and the function terminate() is called.
-
- If the exception thrown from func2() in the inner try block is type_err, the
- program skips out of both try blocks to the second catch block without invoking
- func3(), because no appropriate catch block exists following the inner try
- block. If the entire try block in the example is in a function that has a throw
- list and does not include spec_err on its throw list, unexpected() is called.
-
- You can also nest a try block within a catch block.
-
- Related Information
-
- Catching Exceptions
- Transferring Control
- Using Exception Handling
- Rethrowing an Exception
- Exception Specifications
- unexpected() and terminate() Functions
-
-
- ΓòÉΓòÉΓòÉ 16.4.3. Rethrowing an Exception ΓòÉΓòÉΓòÉ
-
- If a catch block cannot handle the particular exception it has caught, you can
- rethrow the exception. The rethrow expression (throw with no argument) causes
- the originally thrown object to be rethrown.
-
- Because the exception has already been caught at the scope in which the rethrow
- expression occurs, it is rethrown out to the next dynamically enclosing try
- block. Therefore, it cannot be handled by catch blocks at the scope in which
- the rethrow expression occurred. Any catch blocks following the dynamically
- enclosing try block have an opportunity to catch the exception.
-
- Example of Rethrowing an Exception
-
- The rethrow expression can be caught by any catch whose argument matches the
- argument of the exception originally thrown.
-
- Related Information
-
- Catching Exceptions
- Transferring Control
- Using Exception Handling
- Nested Try Blocks
- Using a Conditional Expression in a Throw Expression
- Exception Specifications
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Rethrowing an Exception ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, catch(FileIO) catches any object of type FileIO and
- any objects that are public base classes of the FileIO class. It then checks
- for those exceptions it can handle. For any exception it cannot handle, it
- issues a rethrow expression to rethrow the exception and allow another handler
- in a dynamically enclosing try block to handle the exception.
-
- *
- ************************************************************************/
-
- // This example illustrates rethrowing an exception.
-
- #include <iostream.h>
- class FileIO
- {
- public:
- int notfound;
- int endfile;
- FileIO(); // initialize data members
- // the following member functions throw an exception
- // if an input error occurs
- void advance(int x);
- void clear();
- void put(int x, int y);
- };
- // .
- // .
- // .
- void f()
- {
- FileIO fio;
- try
- {
- // call member functions of FileIO class
- fio.advance (1);
- fio.clear();
- fio.put(1,-1);
- }
-
- catch(FileIO fexc)
- {
- if (fexc.notfound)
- cout << "File not Found" << endl;
- else if (fexc.endfile)
- cout << "End of File" << endl;
- else
- throw; // rethrow to outer handler
- }
- catch(...) { /* ... */ } // catch other exceptions
- }
- main()
- {
- try
- {
- f();
- }
- catch(FileIO) { cout << "Outer Handler" << endl; }
- }
-
- /************************************************************************
- *
-
- The rethrow expression can be caught by any catch whose argument matches the
- argument of the exception originally thrown. Note that, in this example, the
- catch(...) will not catch the rethrow expression because, when the rethrow
- expression is issued, control passes out of the scope of the function f() into
- the next dynamically enclosing block.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 16.4.4. Using a Conditional Expression in a Throw Expression ΓòÉΓòÉΓòÉ
-
- You can use a conditional expression as a throw expression. as shown in the
- following example:
-
- // This example illustrates a conditional expresion
- // used as a throw expression.
-
- #include <iostream.h>
- void main() {
- int doit = 1;
- int dont = 0;
- float f = 8.9;
- int i = 7;
- int j = 6;
- try { throw(doit ? i : f); }
- catch (int x)
- {
- cout << "Caught int " << x << endl;
- }
- catch (float x)
- {
- cout << "Caught float " << x << endl;
- }
- catch (double x)
- {
- cout << "Caught double " << x << endl;
- }
- catch (...)
- {
- cout << "Caught something " << endl;
- }
- }
-
- This example produces the following output because j is of type int:
-
- Caught float 7
-
- At first glance, it looks as if the block that catches integer values should do
- the catch, but i is converted to a float value in the try block because it is
- in a conditional expression with the float value f. If the try block in the
- example is replaced with the following try block:
-
- try { throw doit ? i : j; }
-
- The following output is produced:
-
- Caught int 7
-
- Related Information
-
- Catching Exceptions
- Transferring Control
- Using Exception Handling
- Nested Try Blocks
- Rethrowing an Exception
- Exception Specifications
-
-
- ΓòÉΓòÉΓòÉ 16.5. Constructors and Destructors in Exception Handling ΓòÉΓòÉΓòÉ
-
- When an exception is thrown and control passes to a catch block following a try
- block, destructors are called for all automatic objects constructed since the
- beginning of the try block directly associated with that catch block. If an
- exception is thrown during construction of an object consisting of subobjects
- or array elements, destructors are only called for those subobjects or array
- elements successfully constructed before the exception was thrown. A destructor
- for a local static object will only be called if the object was successfully
- constructed.
-
- For more information on constructors and destructors, see Constructors and
- Destructors Overview.
-
- If a destructor detects an exception and issues a throw, the exception can be
- caught if the caller of the destructor was contained within a try block and an
- appropriate catch is coded.
-
- If an exception is thrown by a function called from an inner try block, but
- caught by an outer try block (because the inner try block did not have an
- appropriate handler), all objects constructed within both the outer and all
- inner try blocks are destroyed. If the thrown object has a destructor, the
- destructor is not called until the exception is caught and handled.
-
- Because a throw expression throws an object and a catch statement can catch an
- object, the object thrown enables error-related information to be transferred
- from the point at which an exception is detected to the exception's handler. If
- you throw an object with a constructor, you can construct an object that
- contains information relevant to the catch expression. The catch block can then
- access information provided by the thrown object.
-
- Example of Using Constructors in Exception Handling
-
- Exception handling can be used in conjunction with constructors and destructors
- to provide resource management that ensures that all locked resources are
- unlocked when an exception is thrown.
-
- Example of Managing Resources with Constructors and Destructors
-
- Related Information
-
- Constructors and Destructors Overview
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
- Exception Specifications
-
-
- ΓòÉΓòÉΓòÉ <hidden> Managing Resources with Constructors and Destructors ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- Exception handling can be used in conjunction with constructors and destructors
- to provide resource management that ensures that all locked resources are
- unlocked when an exception is thrown. For example:
-
- *
- ************************************************************************/
-
- class data
- {
- public:
- void lock(); // prevent other users from
- // changing the object
- void unlock(); // allow other users to change
- // the object
- };
- void q(data&), bar(data&);
- // ...
- main()
- {
- data important;
- important.lock();
- q(important);
- bar(important);
- important.unlock();
- }
-
- /************************************************************************
- *
-
- If q() or bar() throw an exception, important.unlock() will not be called and
- the data will stay locked. This problem can be corrected by using a helper
- class to write an exception-aware program for resource management.
-
- *
- ************************************************************************/
-
- class data
- {
- public:
- void lock(); // prevent other users from
- // changing the object
- void unlock(); // allow other users to change
- // the object
- };
- class locked_data // helper class
- {
- data& real_data;
- public:
- locked_data(data& d) : real_data(d)
- {real_data.lock();}
- ~locked_data() {real_data.unlock();}
- };
- void q(data&), bar(data&);
- // ...
- main()
- {
- data important;
- locked_data my_lock(important);
- q(important);
- bar(important);
- }
-
- /************************************************************************
- *
-
- In this case, if q() or bar() throws an exception, the destructor for my_lock
- will be called, and the data will be unlocked.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Using Constructors in Exception Handling ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- In the following example, an object of class DivideByZero is thrown by the
- function divide(). The constructor copies the string "Division by zero" into
- the char array errname. Because DivideByZero is a derived class of class
- Matherr, the catch block for Matherr catches the thrown exception. The catch
- block can then access information provided by the thrown object, in this case
- the text of an error message.
-
- *
- ************************************************************************/
-
- // This example illustrates constructors and
- // destructors in exception handling.
-
- #include <string.h> // needed for strcpy
- #include <iostream.h>
- class Matherr { public: char errname[30]; };
- class DivideByZero : public Matherr
- {
- public:
- DivideByZero() {strcpy (errname, "Division by zero");}
- };
- double divide(double a, double b)
- {
- if (b == 0) throw DivideByZero();
- return a/b;
- }
-
- void main()
- {
- double a=7,b=0;
- try {divide (a,b);}
- catch (Matherr xx)
- {
- cout << xx.errname << endl;
- }
- }
-
-
- ΓòÉΓòÉΓòÉ 16.6. Exception Specifications ΓòÉΓòÉΓòÉ
-
- C++ provides a mechanism to ensure that a given function is limited to throwing
- only a specified list of exceptions. An exception specification at the
- beginning of any function acts as a guarantee to the function's caller that the
- function will not directly or indirectly throw any exception not contained in
- the exception specification. For example, a function:
-
- void translate() throw(unknown_word,bad_grammar) { /* ... */ }
-
- explicitly states that it will not throw any exception other than unknown_word
- or bad_grammar. The function translate() must handle any exceptions thrown by
- functions it might call, unless those exceptions are specified in the exception
- specification of translate(). If an exception is thrown by a function called by
- translate() and the exception is not handled by translate() or contained in the
- exception specification of translate(), unexpected() is called.
-
- Syntax of an Exception Specification
-
- If an exception is thrown from a function that has not specified the thrown
- exception in its exception specification, the result is a call to the function
- unexpected(), which is discussed in unexpected() and terminate() Functions.
-
- A function with an empty throw() specification guarantees that the function
- will not throw any exceptions. A function without an exception specification
- allows any object to be thrown from the function.
-
- The compiler does not prevent an exception specification from defining a more
- limited set of valid exceptions than the set of exceptions the function may
- actually throw. Such an error is detected only at run time, and only if the
- unspecified exception is thrown.
-
- Example of Throwing an Unspecified Exception
-
- If a function with an exception specification calls a subfunction with a less
- restrictive exception specification (one that contains more objects than the
- calling function's exception specification), any thrown objects from within the
- subfunction that are not handled by the subfunction, and that are not part of
- the outer function's specification list, must be handled within the outer
- function. If the outer function fails to handle an exception not in its
- exception specification, a call to unexpected() is made.
-
- Related Information
-
- unexpected() and terminate() Functions
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
-
-
- ΓòÉΓòÉΓòÉ <hidden> Syntax of an Exception Specification ΓòÉΓòÉΓòÉ
-
- The syntax of the exception specification is:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé
- >>ΓöÇΓöÇthrowΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ)ΓöÇΓöÇ><
- ΓööΓöÇtypeΓöÇΓöÿ
-
- The syntax of a function definition that includes an exception specification
- is:
-
- ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ ΓöîΓöÇ,ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Γöé
- >>ΓöÇΓöÇreturn_typeΓöÇΓöÇfunction_nameΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ)ΓöÇΓöÇthrowΓöÇΓöÇ(ΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼Γö┤ΓöÇΓöÇ>
- ΓööΓöÇargumentΓöÇΓöÿ ΓööΓöÇtypeΓöÇΓöÿ
- >ΓöÇΓöÇ)ΓöÇΓöÇ{ΓöÇΓöÇfunction_bodyΓöÇΓöÇ}ΓöÇΓöÇ><
-
-
- ΓòÉΓòÉΓòÉ <hidden> Example of Throwing an Unspecified Exception ΓòÉΓòÉΓòÉ
-
- In the following example, NameTooShort is thrown from within a function that
- explicitly states that it will only throw NameTooLong. This is a valid
- function, although at run time, if NameTooShort is thrown, a call to
- unexpected() will be made.
-
- #include <string.h> // needed for strlen
- class NameTooLong {};
- class NameTooShort {};
-
- void check(char* fname) throw (NameTooLong)
- {
- if ( strlen(fname)<4 ) throw NameTooShort();
- }
-
-
- ΓòÉΓòÉΓòÉ 16.7. unexpected() and terminate() Functions ΓòÉΓòÉΓòÉ
-
- Not all thrown errors can be caught and successfully dealt with by a catch
- block. In some situations, the best way to handle an exception is to terminate
- the program. Two special library functions are implemented in C++ to process
- exceptions not properly handled by catch blocks or exceptions thrown outside of
- a valid try block. These functions are unexpected() and terminate().
-
- When a function with an exception specification throws an exception that is not
- listed in its exception specification, the function void unexpected() is
- called. Next, unexpected() calls a function specified by the set_unexpected()
- function. By default, unexpected() calls the function terminate().
-
- In some cases, the exception handling mechanism fails and a call to void
- terminate() is made. This terminate() call occurs in any of the following
- situations:
-
- When terminate() is explicitly called
- When no catch can be matched to a thrown object
- When the stack becomes corrupted during the exception-handling process
- When a system defined unexpected() is called
-
- The terminate() function calls a function specified by the set_terminate()
- function. By default, terminate calls abort(), which exits from the program.
-
- A terminate function cannot return to its caller, either by using return or by
- throwing an exception.
-
- Example of Using the Exception Handling Functions
-
- Related Information
-
- set_unexpected() and set_terminate() Functions
- C++ Exception Handling Overview
- Exception Specifications
- Using Exception Handling
- Transferring Control
- abort - Stop a Program
-
-
- ΓòÉΓòÉΓòÉ 16.8. set_unexpected() and set_terminate() Functions ΓòÉΓòÉΓòÉ
-
- The function unexpected(), when invoked, calls the function most recently
- supplied as an argument to set_unexpected(). If set_unexpected() has not yet
- been called, unexpected() calls terminate().
-
- The function terminate(), when invoked, calls the function most recently
- supplied as an argument to set_terminate(). If set_terminate() has not yet been
- called, terminate() calls abort(), which ends the program.
-
- You can use set_unexpected() and set_terminate() to register functions you
- define to be called by unexpected() and terminate(). set_unexpected() and
- set_terminate() are included in the standard header files <unexpect.h>. and
- <terminat.h>. Each of these functions has as its return type and its argument
- type a pointer to function with a void return type and no arguments. The
- pointer to function you supply as the argument becomes the function called by
- the corresponding special function: the argument to set_unexpected() becomes
- the function called by unexpected(), and the argument to set_terminate()
- becomes the function called by terminate(). Both set_unexpected() and
- set_terminate() return a pointer to the function that was previously called by
- their respective special functions (unexpected() and terminate()). By saving
- the return values, you can restore the original special functions later so that
- unexpected() and terminate() will once again call terminate() and abort().
-
- If you use set_terminate() to register your own function, the final action of
- that program should be to exit from the program. If you attempt to return from
- the function called by terminate(), abort() is called instead and the program
- ends.
-
- Note: Providing a call to longjmp() inside a user-defined terminate function
- can transfer execution control to some other desired point. When you call
- longjmp, objects existing at the time of a setjmp call will still exist, but
- some objects constructed after the call to setjmp might not be destructed.
-
- Example of Using the Exception Handling Functions
-
- Related Information
-
- unexpected() and terminate() Functions
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
- abort - Stop a Program
- setjmp - Preserve Stack Environment
- longjmp - Restore Stack Environment
-
-
- ΓòÉΓòÉΓòÉ 16.9. _set_mt_unexpected() and _set_mt_terminate() Functions ΓòÉΓòÉΓòÉ
-
- The function _set_mt_terminate() registers a terminate handler exactly the same
- way set_terminate() does, except that it only affects the current thread. When
- a terminate function needs to be called, the code first checks to see if a
- thread terminate handler has been registered. If so, the thread terminate
- handler is called. If not, the global terminate handler (the one registered
- with set_terminate()) is called.
-
- The function _set_mt_unexpected() registers an unexpected handler exactly the
- same way set_unexpected() does, except that it only affects the current thread.
- When an unexpected handler needs to be called, the code first checks to see if
- a thread unexpected handler has been registered. If so, the thread unexpected
- handler is called. If not, the global unexpected handler (the one registered
- with set_unexpected()) is called.
-
- Related Information
-
- unexpected() and terminate() Functions
- set_unexpected() and set_terminate() Functions
- C++ Exception Handling Overview
- Using Exception Handling
- Transferring Control
- Exception Specifications
-
-
- ΓòÉΓòÉΓòÉ 16.10. Example of Using the Exception Handling Functions ΓòÉΓòÉΓòÉ
-
- /************************************************************************
- *
-
- The following example shows the flow of control and special functions used in
- exception handling:
-
- *
- ************************************************************************/
-
- #include <terminat.h>
- #include <unexpect.h>
- #include <iostream.h>
- class X { /* ... */ };
- class Y { /* ... */ };
- class A { /* ... */ };
- // pfv type is pointer to function returning void
- typedef void (*pfv)();
- void my_terminate()
- { cout << "Call to my terminate" << endl; }
- void my_unexpected()
- { cout << "Call to my unexpected" << endl; }
- void f() throw(X,Y) // f() is permitted to throw objects of class
- // types X and Y only
- {
- A aobj;
- throw(aobj); // error, f() throws a class A object
- }
- main()
- {
- pfv old_term = set_terminate(my_terminate);
- pfv old_unex = set_unexpected(my_unexpected);
- try{ f(); }
- catch(X) { /* ... */ }
- catch(Y) { /* ... */ }
- catch (...) { /* ... */ }
-
- set_unexpected(old_unex);
- try { f();}
- catch(X) { /* ... */ }
- catch(Y) { /* ... */ }
- catch (...) { /* ... */ }
- }
-
- /************************************************************************
- *
-
- At run time, this program behaves as follows:
-
- 1. The call to set_terminate() assigns to old_term the address of the
- function last passed to set_terminate() when set_terminate() was
- previously called.
-
- 2. The call to set_unexpected() assigns to old_unex the address of the
- function last passed to set_unexpected() when set_unexpected() was
- previously called.
-
- 3. Within a try block, function f() is called. Because f() throws an
- unexpected exception, a call to unexpected() is made. unexpected() in
- turn calls my_unexpected(), which prints a message to standard output and
- returns.
-
- 4. The second call to set_unexpected() replaces the user-defined function
- my_unexpected() with the saved pointer to the original function
- (terminate()) called by unexpected().
-
- 5. Within a second try block, function f() is called once more. Because f()
- throws an unexpected exception, a call to unexpected() is again made.
- unexpected() automatically calls terminate(), which calls the function
- my_terminate().
-
- 6. my_terminate() displays a message. It returns, and the system calls
- abort(), which terminates the program.
-
- At run time, the following information is displayed, and the program ends:
-
- Call to my_unexpected
- Call to my_terminate
-
- Note: The catch blocks following the try block are not entered, because the
- exception was handled by my_unexpected() as an unexpected throw, not as a
- valid exception.
-
- *
- ************************************************************************/
-
-
- ΓòÉΓòÉΓòÉ 17. C and C++ Compatibility ΓòÉΓòÉΓòÉ
-
- The differences between ANSI/ISO C and C++ fall into two categories:
-
- Constructs found in C++ but not in ANSI/ISO C
- Constructs found in both C++ and ANSI/ISO C, but treated differently in
- the two languages
-
- C++ contains many constructs that are not found in ANSI/ISO C:
-
- Single line comments beginning with //
- Scope operator (::)
- Free store management using the operators new and delete
- Linkage specification for functions
- Reference types
- Default arguments for functions
- Inline functions
- Classes
- Anonymous unions
- Overloaded operators and functions
- Class templates and function templates
- Exception handling
-
- Note: The VisualAge for C++ compiler also supports anonymous unions in C, but
- the implementation is slightly different from C++. For more information, see
- Anonymous Unions in C.
-
-
- ΓòÉΓòÉΓòÉ 17.1. Constructs Treated Differently in C and C++ ΓòÉΓòÉΓòÉ
-
- Because C++ is based on ANSI/ISO C, the two languages have many constructs in
- common. The use of some of these shared constructs differs, as shown here.
-
- Character Array Initialization
- Character Constants
- Class and typedef Names
- Class and Scope Declarations
- const Object Initialization
- Definitions
- Definitions within Return or Argument Types
- Enumerator Type
- Enumeration Type
- Function Declarations
- Functions with an Empty Argument List
- Global Constant Linkage
- Jump Statements
- Keywords
- main() Recursion
- Names of Nested Classes
- Pointers to void
- Prototype Declarations
- Return without Declared Value
- __STDC__ Macro
- typedefs in Class Declarations
-
- Related Information
-
- C and C++ Compatibility
-
-
- ΓòÉΓòÉΓòÉ 17.1.1. Character Array Initialization ΓòÉΓòÉΓòÉ
-
- In C++, when you initialize character arrays, a trailing '\0' (zero of type
- char) is appended to the string initializer. You cannot initialize a character
- array with more initializers than there are array elements.
-
- In ANSI/ISO C, space for the trailing '\0' can be omitted in this type of
- initialization.
-
- The following initialization, for instance, is not valid in C++:
-
- char v[3] = "asd"; // not valid in C++, valid in ANSI/ISO C
-
- because four elements are required. This initialization produces an error
- because there is no space for the implied trailing '\0' (zero of type char).
-
- For more information, see Arrays.
-
-
- ΓòÉΓòÉΓòÉ 17.1.2. Character Constants ΓòÉΓòÉΓòÉ
-
- A character constant has type char in C++ and int in ANSI/ISO C.
-
- For more information, see Character Constants.
-
-
- ΓòÉΓòÉΓòÉ 17.1.3. Class and typedef Names ΓòÉΓòÉΓòÉ
-
- In C++, a class and a typedef cannot both use the same name to refer to a
- different type within the same scope (unless the typedef is a synonym for the
- class name). In C, a typedef name and a struct tag name declared in the same
- scope can have the same name because they have different name spaces. For
- example:
-
- void main ()
- {
- typedef double db;
- struct db; // error in C++, valid in ANSI/ISO C
-
- typedef struct st st; // valid ANSI/ISO C and C++
- }
-
- For more information on typedef, see typedef. For information on class types,
- see C++ Classes. For information on structures, see Structures.
-
-
- ΓòÉΓòÉΓòÉ 17.1.4. Class and Scope Declarations ΓòÉΓòÉΓòÉ
-
- In C++, a class declaration introduces the class name into the scope where it
- is declared and hides any object, function, or other declaration of that name
- in an enclosing scope. In ANSI/ISO C, an inner scope declaration of a struct
- name does not hide an object or function of that name in an outer scope. For
- example:
-
- double db;
- void main ()
- {
- struct db // hides double object db in C++
- { char* str; };
- int x = sizeof(db); // size of struct in C++
- // size of double in ANSI/ISO C
- }
-
- For more information, see Scope of Class Names. For general information about
- scope, see Scope in C++.
-
-
- ΓòÉΓòÉΓòÉ 17.1.5. const Object Initialization ΓòÉΓòÉΓòÉ
-
- In C++, const objects must be initialized. In ANSI/ISO C, they can be left
- uninitialized.
-
- For more information, see volatile and const Qualifiers.
-
-
- ΓòÉΓòÉΓòÉ 17.1.6. Definitions ΓòÉΓòÉΓòÉ
-
- An object declaration, for example:
-
- int i;
-
- is a definition in C++. In ANSI/ISO C, it is a tentative definition.
-
- In C++, a global data object must be defined only once. In ANSI/ISO C, a global
- data object can be declared several times without using the extern keyword.
-
- In C++, multiple definitions for a single variable cause an error. A C
- compilation unit can contain many identical tentative definitions for a
- variable.
-
- For more information, see Declarations.
-
-
- ΓòÉΓòÉΓòÉ 17.1.7. Definitions within Return or Argument Types ΓòÉΓòÉΓòÉ
-
- In C++, types may not be defined in return or argument types. ANSI/ISO C allows
- such definitions. For example, the declarations:
-
- void print(struct X { int i;} x); // error in C++
- enum count{one, two, three} counter(); // error in C++
-
- produce errors in C++, but are valid declarations in ANSI/ISO C.
-
- For more information, see Function Declarations and Calling Functions and
- Passing Arguments.
-
-
- ΓòÉΓòÉΓòÉ 17.1.8. Enumerator Type ΓòÉΓòÉΓòÉ
-
- An enumerator has the same type as its enumeration in C++. In ANSI/ISO C, an
- enumeration has type int.
-
- For more information on enumerators, see Enumerations.
-
-
- ΓòÉΓòÉΓòÉ 17.1.9. Enumeration Type ΓòÉΓòÉΓòÉ
-
- The assignment to an object of enumeration type with a value that is not of
- that enumeration type produces an error in C++. In ANSI/ISO C, an object of
- enumeration type can be assigned values of any integral type.
-
- For more information, see Enumerations.
-
-
- ΓòÉΓòÉΓòÉ 17.1.10. Function Declarations ΓòÉΓòÉΓòÉ
-
- In C++, all declarations of a function must match the unique definition of a
- function. ANSI/ISO C has no such restriction.
-
- For more information, see Function Declarations.
-
-
- ΓòÉΓòÉΓòÉ 17.1.11. Functions with an Empty Argument List ΓòÉΓòÉΓòÉ
-
- Consider the following function declaration:
-
- int f();
-
- In C++, this function declaration means that the function takes no arguments.
- In ANSI/ISO C, it could take any number of arguments, of any type.
-
- For more information, see Function Declarations.
-
-
- ΓòÉΓòÉΓòÉ 17.1.12. Global Constant Linkage ΓòÉΓòÉΓòÉ
-
- In C++, an object declared const has internal linkage, unless it has previously
- been given external linkage. In ANSI/ISO C, it has external linkage.
-
- For more information, see Program Linkage.
-
-
- ΓòÉΓòÉΓòÉ 17.1.13. Jump Statements ΓòÉΓòÉΓòÉ
-
- C++ does not allow you to jump over declarations containing initializations.
- ANSI/ISO C does allow you to use jump statements for this purpose.
-
- For more information, see Initializers.
-
-
- ΓòÉΓòÉΓòÉ 17.1.14. Keywords ΓòÉΓòÉΓòÉ
-
- C++ contains some additional keywords not found in ANSI/ISO C. C programs that
- use these keywords as identifiers are not valid C++ programs:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 8. C++ Keywords Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé asm Γöé friend Γöé protected Γöé try Γöé
- Γöé catch Γöé inline Γöé public Γöé typeid Γöé
- Γöé class Γöé new Γöé template Γöé virtual Γöé
- Γöé delete Γöé operator Γöé this Γöé wchar_t Γöé
- Γöé dynamic_cast Γöé private Γöé throw Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- Although they are documented in the ANSI/ISO C++ Working Paper, and are
- reserved by the compiler, the following keywords are not yet supported by
- VisualAge for C++:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé Table 9. C++ Keywords Not Supported by VisualAge for C++ Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé bool Γöé false Γöé reinterpret_cast Γöé typename Γöé
- Γöé const_cast Γöé mutable Γöé static_cast Γöé using Γöé
- Γöé explicit Γöé namespace Γöé true Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- If you include the <iso646.h> header, you can represent unavailable characters
- in a source program using the following keywords:
-
- ΓöîΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö¼ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÉ
- Γöé AND Γöé BITOR Γöé NOT_EQ Γöé XOR Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé AND_EQ Γöé COMPL Γöé OR Γöé XOR_EQ Γöé
- Γö£ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö╝ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöñ
- Γöé BITAND Γöé NOT Γöé OR_EQ Γöé Γöé
- ΓööΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓö┤ΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÇΓöÿ
-
- For more information, see Keywords.
-
-
- ΓòÉΓòÉΓòÉ 17.1.15. main() Recursion ΓòÉΓòÉΓòÉ
-
- In C++, main() cannot be called recursively and cannot have its address taken.
- ANSI/ISO C allows recursive calls and allows pointers to hold the address of
- main().
-
- For more information, see The main() Function.
-
-
- ΓòÉΓòÉΓòÉ 17.1.16. Names of Nested Classes ΓòÉΓòÉΓòÉ
-
- In C++, the name of a nested class is local to its enclosing class. In ANSI/ISO
- C, the name of the nested structure belongs to the same scope as the name of
- the outermost enclosing structure.
-
- For more information, see Nested Classes.
-
-
- ΓòÉΓòÉΓòÉ 17.1.17. Pointers to void ΓòÉΓòÉΓòÉ
-
- C++ allows void pointers to be assigned only to other void pointers. In
- ANSI/ISO C, a pointer to void can be assigned to a pointer of any other type
- without an explicit cast.
-
- For more information, see void Type and Pointers.
-
-
- ΓòÉΓòÉΓòÉ 17.1.18. Prototype Declarations ΓòÉΓòÉΓòÉ
-
- C++ requires full prototype declarations. ANSI/ISO C allows nonprototyped
- functions.
-
- For more information, see Function Declarator.
-
-
- ΓòÉΓòÉΓòÉ 17.1.19. Return without Declared Value ΓòÉΓòÉΓòÉ
-
- In C++, a return (either explicit or implicit) from main() that is declared to
- return a value results in an error if no value is returned. A return (either
- explicit or implicit) from all other functions that is declared to return a
- value must return a value. In ANSI/ISO C, a function that is declared to return
- a value can return with no value, with unspecified results.
-
- For more information, see Function Return Values.
-
-
- ΓòÉΓòÉΓòÉ 17.1.20. __STDC__ Macro ΓòÉΓòÉΓòÉ
-
- The predefined macro variable __STDC__ is not defined for C++. It has the
- integer value 0 when used in a #if statement, indicating that the C++ language
- is not a proper superset of C, and that the compiler does not conform to
- ANSI/ISO C. In ANSI/ISO C, __STDC__ has the integer value 1.
-
- For more information on macros, see Predefined Macro Names.
-
-
- ΓòÉΓòÉΓòÉ 17.1.21. typedefs in Class Declarations ΓòÉΓòÉΓòÉ
-
- In C++, a typedef name may not be redefined in a class declaration after being
- used in the declaration. ANSI/ISO C allows such a declaration. For example:
-
- void main ()
- {
- typedef double db;
- struct st
- {
- db x;
- double db; // error in C++, valid in ANSI/ISO C
- };
- }
-
- For more information, see typedef.
-
-
- ΓòÉΓòÉΓòÉ 18. Glossary ΓòÉΓòÉΓòÉ
-
- This glossary defines terms and abbreviations that are used in this book.
- Included are terms and definitions from the following sources:
-
- American National Standard Dictionary for Information Systems, American
- National Standard for Information Systems X3.172-1990, copyright 1990 by
- the American National Standards Institute (American National Standard for
- Information Systems). Copies may be purchased from the American National
- Standards Institute, 1430 Broadway, New York, New York 10018. Such
- definitions are indicated by the symbol American National Standard for
- Information Systems after the definition.
-
- IBM Dictionary of Computing, SC20-1699. These definitions are indicated
- by the registered trademark IBM after the definition.
-
- X/Open CAE Specification. Commands and Utilities, Issue 4. July, 1992.
- These definitions are indicated by the symbol X/Open after the
- definition.
-
- ISO/IEC 9945-1:1990/IEEE POSIX 1003.1-1990. These definitions are
- indicated by the symbol ISO.1 after the definition.
-
- The Information Technology Vocabulary, developed by Subcommittee 1, Joint
- Technical Committee 1, of the International Organization for
- Standardization and the International Electrotechnical Commission
- (ISO/IEC JTC1/SC1). Definitions of published parts of this vocabulary are
- identified by the symbol ISO-JTC1 after the definition; definitions taken
- from draft international standards, committee drafts, and working papers
- being developed by ISO/IEC JTC1/SC1 are identified by the symbol ISO
- Draft after the definition, indicating that final agreement has not yet
- been reached among the participating National Bodies of SC1.
-
- A J S
- B K T
- C L U
- D M V
- E N W
- F O X
- G P Y
- H Q Z
- I R
-
-
- ΓòÉΓòÉΓòÉ <hidden> A ΓòÉΓòÉΓòÉ
-
- abstract class
-
- 1. A class with at least one pure virtual function that is used as
- a base class for other classes. The abstract class represents a
- concept; classes derived from it represent implementations of
- the concept. You cannot construct an object of an abstract
- class. See also base class.
-
- 2. A class that allows polymorphism.
-
- abstract data type A mathematical model that includes a structure for storing
- data and operations that can be performed on that data. Common
- abstract data types include sets, trees, and heaps.
-
- abstraction (data) See data abstraction.
-
- access An attribute that determines whether or not a class member is
- accessible in an expression or declaration. It can be public,
- protected, or private.
-
- access declaration A declaration used to adjust access to members of a base
- class.
-
- access resolution The process by which the accessibility of a particular class
- member is determined.
-
- access specifier One of the C++ keywords public, private, or protected.
-
- aggregate
-
- 1. An array or a structure.
-
- 2. A compile-time option to show the layout of a structure or
- union in the listing.
-
- 3. An array or a class object with no private or protected
- members, no constructors, no base classes, and no virtual
- functions.
-
- 4. In programming languages, a structured collection of data items
- that form a data type. ISO-JTC1.
-
- alignment The storing of data in relation to certain machine-dependent
- boundaries. IBM.
-
- ambiguous derivation A derivation where the class is derived from two or more
- base classes that have members with the same name.
-
- American National Standards Institute See American National Standard for
- Information Systems.
-
- angle brackets The characters < (left angle bracket) and > (right angle
- bracket). When used in the phrase "enclosed in angle brackets", the
- symbol < immediately precedes the object to be enclosed, and >
- immediately follows it.
-
- anonymous union A union that is declared within a structure or class and that
- does not have a name.
-
- American National Standard for Information Systems (American National
- Standards Institute) An organization consisting of producers, consumers, and
- general interest groups, that establishes the procedures by which
- accredited organizations create and maintain voluntary industry
- standards in the United States. American National Standard for
- Information Systems.
-
- array An aggregate that consists of data objects, with identical
- attributes, each of which may be uniquely referenced by
- subscripting.
-
- array element A data element in an array.
-
- ASCII (American National Standard Code for Information Interchange) The
- standard code, using a coded character set consisting of 7-bit coded
- characters (8 bits including parity check), that is used for
- information interchange among data processing systems, data
- communication systems, and associated equipment. The ASCII set
- consists of control characters and graphic characters.
-
- Note: IBM has defined an extension to ASCII code (characters
- 128-255).
-
- assignment expression An operation that stores the value of the right operand
- in the storage location specified by the left operand.
-
- automatic data Data that does not persist after a routine has finished
- executing. Automatic data may be automatically initialized to a
- certain value upon entry and reentry to a routine.
-
- automatic storage Storage that is allocated on entry to a routine or block and
- is freed on the subsequent return. Sometimes referred to as stack
- storage or dynamic storage.
-
-
- ΓòÉΓòÉΓòÉ <hidden> B ΓòÉΓòÉΓòÉ
-
- backslash The character \.
-
- base class A class from which other classes are derived. A base class may
- itself be derived from another base class. See also abstract class.
-
- binary expression An operation containing two operands and one operator.
-
- bit field A member of a structure or union that contains a specified number of
- bits.
-
- block
-
- 1. In programming languages, a compound statement that coincides
- with the scope of at least one of the declarations contained
- within it. A block may also specify storage allocation or
- segment programs for other purposes. ISO-JTC1.
-
- 2. A string of data elements recorded or transmitted as a unit.
- The elements may be characters, words, or physical records. ISO
- Draft.
-
- 3. The unit of data transmitted to and from a device. Each block
- contains one record, part of a record, or several records.
-
- boundary alignment The position in main storage of a fixed-length field (such
- as byte or doubleword) on an integral boundary for that unit of
- information.
-
- For the Class Library example, a word boundary is a storage address
- evenly divisible by two.
-
- brackets The characters [ (left bracket) and ] (right bracket), also known as
- square brackets. When used in the phrase "enclosed in (square)
- brackets" the symbol [ immediately precedes the object to be
- enclosed, and ] immediately follows it.
-
- built-in A function that the compiler automatically puts inline instead of
- generating a call to the function. Synonymous with predefined. IBM.
-
-
- ΓòÉΓòÉΓòÉ <hidden> C ΓòÉΓòÉΓòÉ
-
- C++ class library See class library.
-
- C++ library A system library that contains common C++ language subroutines for
- file access, memory allocation, and other functions.
-
- call To transfer control to a procedure, program, routine, or subroutine.
- IBM.
-
- caller A routine that calls another routine.
-
- cast A notation used to express the conversion of one type to another.
-
- catch block A block associated with a try block that receives control when a
- C++ exception matching its argument is thrown.
-
- character
-
- 1. A letter, digit, or other symbol that is used as part of the
- organization, control, or representation of data. A character
- is often in the form of a spatial arrangement of adjacent or
- connected strokes. American National Standard for Information
- Systems.
-
- 2. A sequence of one or more bytes representing a single graphic
- symbol or control code. This term corresponds to the ISO C
- standard term multibyte character (multi-byte character), where
- a single-byte character is a special case of the multi-byte
- character. Unlike the usage in the ISO C standard, character
- here has no necessary relationship with storage space, and byte
- is used when storage space is discussed. X/Open. ISO.1.
-
- character array An array of type char. X/Open.
-
- character constant
-
- 1. A constant with a character value. IBM.
-
- 2. A string of any of the characters that can be represented,
- usually enclosed in apostrophes. IBM.
-
- 3. In some languages, a character enclosed in apostrophes. IBM.
-
- character set
-
- 1. A finite set of different characters that is complete for a
- given purpose; for example, the character set in ISO Standard
- 646, 7-bit Coded Character Set for Information Processing
- Interchange. ISO Draft.
-
- 2. All the valid characters for a programming language or for a
- computer system. IBM.
-
- 3. A group of characters used for a specific reason; for example,
- the set of characters a printer can print. IBM.
-
- character string A contiguous sequence of characters terminated by and
- including the first null byte. X/Open.
-
- class
-
- 1. A group of objects that share a common definition and that
- therefore share common properties, operations, and behavior.
-
- 2. A C++ aggregate that may contain functions, types, and
- user-defined operators in addition to data. Classes can be
- defined hierarchically, allowing one class to be an expansion
- of another, and classes can restrict access to their members.
-
- class key Any of the three C++ keywords: class, struct, or union.
-
- class hierarchy A tree-like structure showing relationships among classes. It
- places one abstract class at the top (a base class) and one or more
- layers of derived classes below it.
-
- class identifier (CLSID) In Windows 95, the globally unique identifier for an
- object. The Win32 Registry uses the CLSID to distinguish all OLE
- objects available on a system. A CLSID is a 16-bit value that
- contains 32 hexadecimal digits.
-
- Also commonly referred to as a globally unique identifier (GUID).
-
- class library A collection of classes.
-
- class template A blueprint describing how a set of related classes can be
- constructed.
-
- class name A unique identifier of a class type that becomes a reserved word
- within its scope.
-
- class scope The scope of class member names.
-
- class tag See class name.
-
- C library A system library that contains common C language subroutines for
- file access, string operators, character operations, memory
- allocation, and other functions. IBM.
-
- code page
-
- 1. An assignment of graphic characters and control function
- meanings to all code points; for example, assignment of
- characters and meanings to 256 code points for an 8-bit code,
- or assignment of characters and meanings to 128 code points for
- a 7-bit code.
-
- 2. A particular assignment of hexadecimal identifiers to graphic
- characters.
-
- collating sequence
-
- 1. A specified arrangement used in sequencing. ISO-JTC1. American
- National Standard for Information Systems.
-
- 2. An ordering assigned to a set of items, such that any two sets
- in that assigned order can be collated. American National
- Standard for Information Systems.
-
- 3. The relative ordering of collating elements as determined by
- the setting of the LC_COLLATE category in the current locale.
- The character order, as defined for the LC_COLLATE category in
- the current locale, defines the relative order of all collating
- elements, such that each element occupies a unique position in
- the order. This is the order used in ranges of characters and
- collating elements in regular expressions and pattern matching.
- In addition, the definition of the collating weights of
- characters and collating elements uses collating elements to
- represent their respective positions within the collation
- sequence.
-
- collation The logical ordering of character or wide-character strings
- according to defined precedence rules. These rules identify a
- collation sequence between the collating elements, and such
- additional rules that can be used to order strings consisting or
- multiple collating elements. X/Open.
-
- comma expression An expression that contains two operands separated by a
- comma. Although the compiler evaluates both operands, the value of
- the expression is the value of the right operand. If the left
- operand produces a value, the compiler discards this value.
- Typically, the left operand of a comma expression is used to produce
- side effects.
-
- compilation unit
-
- 1. A portion of a computer program sufficiently complete to be
- compiled correctly. IBM.
-
- 2. A single compiled file and all its associated include files.
-
- 3. An independently compilable sequence of high-level language
- statements. Each high-level language product has different
- rules for what makes up a compilation unit.
-
- complete class name The complete qualification of a nested class name
- including all enclosing class names.
-
- Compound Object Model (COM) The underlying model for all OLE services. It
- consists of a variety of APIs and object interfaces that allow
- container components to communicate and interact with one another.
-
- condition
-
- 1. A relational expression that can be evaluated to a value of
- either true or false. IBM.
-
- 2. An exception that has been enabled, or recognized, by the
- Language Environment and thus is eligible to activate user and
- language condition handlers. Any alteration to the normal
- programmed flow of an application. Conditions can be detected
- by the hardware/operating system and result in an interrupt.
- They can also be detected by language-specific generated code
- or language library code.
-
- conditional expression A compound expression that contains a condition (the
- first expression), an expression to be evaluated if the condition
- has a nonzero value (the second expression), and an expression to be
- evaluated if the condition has the value zero (the third
- expression).
-
- const
-
- 1. An attribute of a data object that declares that the object
- cannot be changed.
-
- 2. An attribute of a function that declares that the function will
- not modify data members of its class.
-
- constant
-
- 1. In programming languages, a language object that takes only one
- specific value. ISO-JTC1.
-
- 2. A data item with a value that does not change. IBM.
-
- constant expression An expression having a value that can be determined during
- compilation and that does not change during the running of the
- program. IBM.
-
- constructor A special class member function that has the same name as the
- class and is used to construct and, possibly, initialize objects of
- its class type. A return type is not specified.
-
- control character
-
- 1. A character whose occurrence in a particular context specifies
- a control function. ISO Draft.
-
- 2. Synonymous with nonprinting character. IBM.
-
- 3. A character, other than a graphic character, that affects the
- recording, processing, transmission, or interpretation of text.
- X/Open.
-
- conversion
-
- 1. In programming languages, the transformation between values
- that represent the same data item but belong to different data
- types. Information may be lost because of conversion since
- accuracy of data representation varies among different data
- types. ISO-JTC1.
-
- 2. The process of changing from one method of data processing to
- another or from one data processing system to another. IBM.
-
- 3. The process of changing from one form of representation to
- another; for example to change from decimal representation to
- binary representation. IBM.
-
- 4. A change in the type of a value. For example, when you add
- values having different data types, the compiler converts both
- values to a common form before adding the values.
-
- conversion function A member function that specifies a conversion from its
- class type to another type.
-
- copy constructor A constructor used to make a copy of an object from another
- object of the same type.
-
-
- ΓòÉΓòÉΓòÉ <hidden> D ΓòÉΓòÉΓòÉ
-
- data abstraction A data type with a private representation and a public set of
- operations. The C++ language uses the concept of classes to
- implement data abstraction.
-
- data member The smallest possible piece of complete data. Elements are
- composed of data members.
-
- data structure The internal data representation of an implementation.
-
- data type The properties and internal representation that characterize data.
-
- DBCS (Double-Byte Character Set) See double-byte character set.
-
- decimal constant
-
- 1. A numerical data type used in standard arithmetic operations.
-
- 2. A number containing any of the digits 0 through 9. IBM.
-
- declaration Introduces a name to a program and specifies how the name is to be
- interpreted.
-
- declare To specify the interpetation that C++ gives to each identifier.
-
- default argument An argument that is declared with a default value in a
- function prototype or declaration. If a call to the function omits
- this argument, the default value is used. Arguments with default
- values must be the trailing arguments in a function prototype
- argument list.
-
- default constructor A constructor that takes no arguments, or a constructor
- for which all the arguments have default values.
-
- default initialization The initial value assigned to a data object by the
- compiler if no initial value is specified by the programmer. extern
- and static variables receive a default initialization of zero, while
- the default initial value for auto and register variables is
- undefined.
-
- define directive A preprocessor statement that directs the preprocessor to
- replace an identifier or macro invocation with special code.
-
- definition
-
- 1. A data description that reserves storage and may provide an
- initial value.
-
- 2. A declaration that allocates storage, and may initialize a data
- object or specify the body of a function.
-
- delete
-
- 1. A C++ keyword that identifies a free-storage deallocation
- operator.
-
- 2. A C++ operator used to destroy objects created by operator new.
-
- demangling The conversion of mangled names back to their original source code
- names. During C++ compilation, identifiers such as function and
- static class member names are mangled (encoded) with type and
- scoping information to ensure type-safe linkage. These mangled names
- appear in the object file and the final executable file. Demangling
- (decoding) converts these names back to their original names to make
- program debugging easier. See also mangling.
-
- derivation
-
- 1. The creation of a new or derived class from an existing base
- class.
-
- 2. The relationship between a class and the classes above or below
- it in a class hierarchy.
-
- derived class A class that inherits from a base class. You can add new data
- members and member functions to the derived class. You can
- manipulate a derived class object as if it were a base class object.
- The derived class can override virtual functions of the base class.
-
- Synonym for child class and subclass.
-
- destructor A special member function that has the same name as its class,
- preceded by a tilde (~), and that "cleans up" after an object of
- that class, for example, by freeing storage that was allocated when
- the object was created. A destructor has no arguments, and no return
- type is specified.
-
- double-byte character set (DBCS) A set of characters in which each character
- is represented by 2 bytes. Languages such as Japanese, Chinese, and
- Korean, which contain more symbols than can be represented by 256
- code points, require double-byte character sets.
-
- Because each character requires 2 bytes, you need hardware and
- supporting software that are DBCS-enabled to enter, display, and
- print DBCS characters.
-
- double-precision Pertaining to the use of two computer words to represent a
- number in accordance with the required precision. ISO-JTC1. American
- National Standard for Information Systems.
-
- doubleword A contiguous sequence of bits or characters that comprises two
- computer words and can be addressed as a unit. For the C Set++ for
- AIX compiler, a doubleword is 32 bits (4 bytes).
-
- dynamic Pertaining to an operation that occurs at the time it is needed
- rather than at a predetermined or fixed time. IBM.
-
- dynamic binding Resolution of a call to a virtual member function at run time.
-
- dynamic link library (DLL) A file containing executable code and data bound to
- a program at load time or run time. The code and data in a dynamic
- link library can be shared by several applications simultaneously.
-
- dynamic storage Synonym for automatic storage.
-
-
- ΓòÉΓòÉΓòÉ <hidden> E ΓòÉΓòÉΓòÉ
-
- element The component of an array, subrange, enumeration, or set.
-
- encapsulation The hiding of the internal representation of objects and
- implementation details from the client program.
-
- enumeration constant An identifier that is defined in an enumeration and that
- has an associated constant integer value. You can use an enumeration
- constant anywhere an integer constant is allowed.
-
- entry point In assembler language, the address or label of the first
- instruction that is executed when a routine is entered for
- execution.
-
- enumeration constant An identifier that is defined in an enumeration and that
- has an associated constant integer value. You can use an enumeration
- constant anywhere an integer constant is allowed.
-
- enumeration data type A type that represents integers and a set of enumeration
- constants. Each enumeration constant has an associated integer
- value.
-
- enumeration tag The identifier that names an enumeration data type.
-
- enumerator In the C and C++ language, an enumeration constant and its
- associated value. IBM.
-
- environment variable Any of a number of variables that describe the way an
- operating system is going to run and the devices it is going to
- recognize.
-
- escape sequence
-
- 1. A representation of a character. An escape sequence contains
- the \ symbol followed by one of the characters: a, b, f, n, r,
- t, v, ', ", x, \, or followed by one or more octal or
- hexadecimal digits.
-
- 2. A sequence of characters that represent, for example,
- nonprinting characters, or the exact code point value to be
- used to represent variant and nonvariant characters regardless
- of code page.
-
- 3. In the C and C++ language, an escape character followed by one
- or more characters. The escape character indicates that a
- different code, or a different coded character set, is used to
- interpret the characters that follow. Any member of the
- character set used at runtime can be represented using an
- escape sequence.
-
- 4. A character that is preceded by a backslash character and is
- interpreted to have a special meaning to the operating system.
-
- 5. A sequence sent to a terminal to perform actions such as moving
- the cursor, changing from normal to reverse video, and clearing
- the screen. Synonymous with multibyte control. IBM.
-
- exception
-
- 1. A user or system error detected by the system and passed to an
- operating system or user exception handler.
-
- 2. For C++, any user, logic, or system error detected by a
- function that does not itself deal with the error but passes
- the error on to a handling routine (also called "throwing the
- exception").
-
- exception handler
-
- 1. A function that is invoked when an exception is detected, and
- that either corrects the problem and returns execution to the
- program, or terminates the program.
-
- 2. In C++, a catch block that catches a C++ exception when it is
- thrown from a function in a try block.
-
- exception handling A type of error handling that allows control and
- information to be passed to an exception handler when an exception
- occurs. Under the Windows operating system, exceptions are generated
- by the system and handled by user code. In C++, try, catch, and
- throw expressions are the constructs used to implement C++ exception
- handling.
-
- executable file A regular file acceptable as a new process image file by the
- equivalent of the exec family of functions, and thus usable as one
- form of a utility. The standard utilities described as compilers can
- produce executable files, but other unspecified methods of producing
- executable files may also be provided. The internal format of an
- executable file is unspecified, but a conforming application cannot
- assume an executable file is a text file. X/Open.
-
- external data definition A definition appearing outside a function. The
- defined object is accessible to all functions that follow the
- definition and are located within the same source file as the
- definition.
-
-
- ΓòÉΓòÉΓòÉ <hidden> F ΓòÉΓòÉΓòÉ
-
- file scope A name declared outside all blocks and classes has file scope and
- can be used after the point of declaration in a source file.
-
- filter A command whose operation consists of reading data from standard
- input or a list of input files and writing data to standard output.
- Typically, its function is to perform some transformation on the
- data stream.
-
- for statement A looping statement that contains the word for followed by a
- list of expressions enclosed in parentheses (the condition) and a
- statement (the action). Each expression in the parenthesized list is
- separated by a semicolon. You can omit any of the expressions, but
- you cannot omit the semicolons.
-
- free store Dynamically allocated memory. New and delete are used to allocate
- and deallocate free store.
-
- friend class A class in which all the member functions are granted access to
- the private and protected members of another class. It is named in
- the declaration of the other class with the prefix friend.
-
- friend function A function that is granted access to the private and protected
- parts of a class. It is named in the declaration of the class with
- the prefix friend.
-
- function A named group of statements that can be called and evaluated and can
- return a value to the calling statement. IBM.
-
- function call An expression that moves the path of execution from the current
- function to a specified function and evaluates to the return value
- provided by the called function. A function call contains the name
- of the function to which control moves and a parenthesized list of
- values. IBM.
-
- function declarator The part of a function definition that names the function,
- provides additional information about the return value of the
- function, and lists the function parameters.
-
- function definition The complete description of a function. A function
- definition contains an optional storage class specifier, an optional
- type specifier, a function declarator, optional parameter
- declarations, and a block statement (the function body).
-
- function prototype A function declaration that provides type information for
- each parameter. It is the first line of the function (header)
- followed by a ; (semicolon). The declaration is required by the
- compiler at the time that the function is declared, so that the
- compiler can check the type.
-
- function scope The capacity to be used anywhere in a function. Labels that are
- declared in a function have function scope.
-
- function template Provides a blueprint describing how a set of related
- individual functions can be constructed.
-
-
- ΓòÉΓòÉΓòÉ <hidden> G ΓòÉΓòÉΓòÉ
-
- generic class See class templates.
-
- global Pertaining to information available to more than one program or
- subroutine. IBM.
-
- global scope See file scope.
-
- global variable A symbol defined in one program module that is used in other
- independently compiled program modules.
-
-
- ΓòÉΓòÉΓòÉ <hidden> H ΓòÉΓòÉΓòÉ
-
- header file A file that can contain system-defined control information or user
- data and generally consists of declarations.
-
- heap An unordered flat collection that allows duplicate elements.
-
- heap storage An area of storage used for allocation of storage whose lifetime
- is not related to the execution of the current routine. The heap
- consists of the initial heap segment and zero or more increments.
-
- hexadecimal constant A constant, usually starting with special characters,
- that contains only hexadecimal digits. Three examples for the
- hexadecimal constant with value 0 would be '\x00', '0x0', or '0X00'.
-
-
- ΓòÉΓòÉΓòÉ <hidden> I ΓòÉΓòÉΓòÉ
-
- identifier
-
- 1. One or more characters used to identify or name a data element
- and possibly to indicate certain properties of that data
- element. American National Standard for Information Systems.
-
- 2. In programming languages, a token that names a data object such
- as a variable, an array, a record, a subprogram, or a function.
- American National Standard for Information Systems.
-
- 3. A sequence of letters, digits, and underscores used to identify
- a data object or function. IBM.
-
- if statement A conditional statement that contains the keyword if, followed by
- an expression in parentheses (the condition), a statement (the
- action), and an optional else clause (the alternative action). IBM.
-
- include directive A preprocessor directive that causes the preprocessor to
- replace the statement with the contents of a specified file.
-
- include file See header file.
-
- incomplete class declaration A class declaration that does not define any
- members of a class. Typically, you use an incomplete class
- declaration as a forward declaration.
-
- incomplete type A type that has no value or meaning when it is first declared.
- There are three incomplete types: void, arrays of unknown size and
- structures and unions of unspecified content. A void type can never
- be completed. Arrays of unknown size and structures or unions of
- unspecified content can be completed in further declarations.
-
- indirection
-
- 1. A mechanism for connecting objects by storing, in one object, a
- reference to another object.
-
- 2. In the C and C++ languages, the application of the unary
- operator * to a pointer to access the object the pointer points
- to.
-
- inheritance
-
- 1. An object-oriented programming technique that allows you to use
- existing classes as bases for creating other classes.
-
- 2. A mechanism by which a derived class can use the attributes,
- relationships, and member functions defined in more abstract
- classes related to it (its base classes). See also multiple
- inheritance.
-
- initializer An expression used to initialize objects. In the C++ language,
- there are three types of initializers:
-
- 1. An expression followed by an assignment operator is used to
- initialize fundamental data type objects or class objects that
- have copy constructors.
- 2. An expression enclosed in braces ( { } ) is used to initialize
- aggregates.
- 3. A parenthesized expression list is used to initialize base
- classes and members using constructors.
-
- inlined function A function call that the compiler replaces with the actual
- code for the function. You can direct the compiler to inline a
- function with the inline keyword.
-
- instance (of a class) An object that is a member of that class. An object
- created according to the definition of that class.
-
- instantiate To create or generate a particular instance or object of a data
- type. For example, an instance box1 of class box could be
- instantiated with the declaration:
-
- box box1;
-
- integer constant A decimal, octal, or hexadecimal constant.
-
- integral object A character object, an object having an enumeration type, an
- object having variations of the type int, or an object that is a bit
- field.
-
- iteration The process of repeatedly applying a function to a series of
- elements in a collection until some condition is satisfied.
-
-
- ΓòÉΓòÉΓòÉ <hidden> K ΓòÉΓòÉΓòÉ
-
- keyword
-
- 1. A predefined word reserved for the C or C++ language that you
- cannot use as an identifier.
-
- 2. A symbol that identifies a parameter.
-
-
- ΓòÉΓòÉΓòÉ <hidden> L ΓòÉΓòÉΓòÉ
-
- label An identifier within or attached to a set of data elements.
-
- ISO Draft.
-
- late binding See dynamic binding.
-
- library
-
- 1. A collection of functions, function calls, subroutines, or
- other data.
-
- 2. A set of object modules that can be specified in a link
- command.
-
- link To interconnect items of data or portions of one or more computer
- programs; for example, linking of object programs by a linkage
- editor to produce an executable file.
-
- linkage editor Synonym for linker.
-
- linker A program that resolves cross-references between separately compiled
- object modules and then assigns final addresses to create a single
- executable program.
-
- literal
-
- 1. In programming languages, a lexical unit that directly
- represents a value; for example, 14 represents the integer
- fourteen, "APRIL" represents the string of characters APRIL,
- 3.0005E2 represents the number 300.05. ISO-JTC1.
-
- 2. A symbol or a quantity in a source program that is itself data,
- rather than a reference to data. IBM.
-
- 3. A character string whose value is given by the characters
- themselves; for example, the numeric literal 7 has the value 7,
- and the character literal CHARACTERS has the value CHARACTERS.
- IBM.
-
- local
-
- 1. In programming languages, pertaining to the relationship
- between a language object and a block such that the language
- object has a scope contained in that block. ISO-JTC1.
-
- 2. Pertaining to that which is defined and used only in one
- subdivision of a computer program. American National Standard
- for Information Systems.
-
- local scope A name declared in a block, which can only be used in that block.
-
- locale The definition of the subset of a user's environment that depends on
- language and cultural conventions.
-
- lvalue An expression that represents an object that can be both examined
- and altered.
-
-
- ΓòÉΓòÉΓòÉ <hidden> M ΓòÉΓòÉΓòÉ
-
- macro An identifier followed by arguments (may be a parenthesized list of
- arguments) that the preprocessor replaces with the replacement code
- located in a preprocessor #define directive.
-
- main function An external function with the identifier main that is the first
- user function-aside from exit routines and C++ static object
- constructors-to get control when program execution begins. Each C
- and C++ program must have exactly one function named main.
-
- mangling The encoding during compilation of identifiers such as function and
- variable names to include type and scope information. The prelinker
- uses these mangled names to ensure type-safe linkage. See also
- demangling.
-
- member function
-
- 1. An operator or function that is declared as a member of a
- class. A member function has access to the private and
- protected data members and member functions of objects of its
- class. Member functions are also called methods.
-
- 2. A function that performs operations on a class.
-
- message A request from one object that the receiving object implement a
- method. Because data is encapsulated and not directly accessible, a
- message is the only way to send data from one object to another.
- Each message specifies the name of the receiving object, the method
- to be implemented, and any parameters the method needs for
- implementation.
-
- method Synonym for member function.
-
- module A program unit that usually performs a particular function or
- related functions, and that is distinct and identifiable with
- respect to compiling, combining with other units, and loading.
-
- multibyte character A mixture of single-byte characters from a single-byte
- character set and double-byte characters from a double-byte
- character set.
-
- multiple inheritance
-
- 1. An object-oriented programming technique implemented in C++
- through derivation, in which the derived class inherits members
- from more than one base class.
-
- 2. The structuring of inheritance relationships among classes so a
- derived class can use the attributes, relationships, and
- functions used by more than one base class.
-
- See also inheritance.
-
- multithread Pertaining to concurrent operation of more than one path of
- execution within a computer.
-
-
- ΓòÉΓòÉΓòÉ <hidden> N ΓòÉΓòÉΓòÉ
-
- name In the C++ language, a name is commonly referred to as an
- identifier. However, syntactically, a name can be an identifier,
- operator function name, conversion function name, destructor name,
- or qualified name.
-
- nested class A class defined within the scope of another class.
-
- new
-
- 1. A C++ keyword identifying a free storage allocation operator.
-
- 2. A C++ operator used to create class objects.
-
- new-line character A control character that causes the print or display
- position to move to the first position on the next line. This
- control character is represented by \n in the C language.
-
- nonreentrant The state of 16-bit code in the kernel where two threads cannot
- access it at the same time without risking a system crash.
-
- In Windows 95, processes are preempted and any thread is likely to
- be interrupted at any point in its execution.
-
- NULL In the C and C++ languages, a pointer that does not point to a data
- object. IBM.
-
- null character (\0) The character with the hex value 00 (all bits turned off).
- It is used to represent the absence of a printed or displayed
- character.
-
- null pointer The value that is obtained by converting the number 0 into a
- pointer; for example, (void *) 0. The C and C++ languages guarantee
- that this value will not match that of any legitimate pointer, so it
- is used by many functions that return pointers to indicate an error.
- X/Open.
-
- number sign The character #, also known as pound sign and hash sign.
-
-
- ΓòÉΓòÉΓòÉ <hidden> O ΓòÉΓòÉΓòÉ
-
- object
-
- 1. A computer representation of something that a user can work
- with to perform a task. An object can appear as text or an
- icon.
-
- 2. A collection of data and member functions that operate on that
- data, which together represent a logical entity in the system.
- In object-oriented programming, objects are grouped into
- classes that share common data definitions and member
- functions. Each object in the class is said to be an instance
- of the class.
-
- 3. In Visual Builder, an instance of an object class consisting of
- attributes, a data structure, and operational member functions.
- It can represent a person, place, thing, event, or concept.
- Each instance has the same properties, attributes, and member
- functions as other instances of the object class, though it has
- unique values assigned to its attributes.
-
- 4. In Windows, any item that is or can be linked into another
- Windows application, such as a sound, graphic, piece of text,
- or portion of a spreadsheet. An object must be from an
- application that supports OLE. See object linking and embedding
- (OLE).
-
- object code Machine-executable instructions, usually generated by a compiler
- from source code written in a higher level language (such as the C++
- language). For programs that must be linked, object code consists of
- relocatable machine code.
-
- object linking and embedding (OLE)
-
- 1. An API that supports compound documents, cross-application
- macro control, and common object registration. OLE defines
- protocols for in-place editing, drag-and-drop data transfers,
- structured storage, custom controls, and more.
-
- 2. A data-sharing scheme that allows dissimilar applications to
- create single complex documents cooperatively. The documents
- can consist of material that a single application could not
- have created on its own.
-
- OLE See object linking and embedding.
-
- operation class A class that defines all required element and key operations
- required by a specific collection implementation.
-
- object module
-
- 1. All or part of an object program sufficiently complete for
- linking. Assemblers and compilers usually produce object
- modules. ISO Draft.
-
- 2. A set of instructions in machine language produced by a
- compiler from a source program. IBM.
-
- object-oriented programming A programming approach based on the concepts of
- data abstraction and inheritance. Unlike procedural programming
- techniques, object-oriented programming concentrates on what data
- objects comprise the problem and how they are manipulated, not on
- how something is accomplished.
-
- octal constant The digit 0 (zero) followed by any digits 0 through 7.
-
- operator function An overloaded operator that is either a member of a class or
- that takes at least one argument that is a class type or a reference
- to a class type. See overloading.
-
- operator precedence In programming languages, an order relation defining the
- sequence of the application of operators within an expression.
- ISO-JTC1.
-
- overflow A condition that occurs when a portion of the result of an operation
- exceeds the capacity of the intended unit of storage.
-
- overloading An object-oriented programming technique where one or more
- function declarations are specified for a single name in the same
- scope.
-
-
- ΓòÉΓòÉΓòÉ <hidden> P ΓòÉΓòÉΓòÉ
-
- pack To store data in a compact form in such a way that the original form
- can be recovered.
-
- pad To fill unused positions in a field with data, usually 0's, 1's, or
- blanks.
-
- parameter
-
- 1. In the C and C++ languages, an object declared as part of a
- function declaration or definition that acquires a value on
- entry to the function, or an identifier following the macro
- name in a function-like macro definition. X/Open.
-
- 2. Data passed between programs or procedures. IBM.
-
- parameter declaration A description of a value that a function receives. A
- parameter declaration determines the storage class and the data type
- of the value.
-
- pointer A variable that holds the address of a data object or function.
-
- pointer class A class that implements pointers.
-
- pointer to member An operator used to access the address of nonstatic members
- of a class.
-
- polymorphism The technique of taking an abstract view of an object or function
- and using any concrete objects or arguments that are derived from
- this abstract view.
-
- precedence The priority system for grouping different types of operators with
- their operands.
-
- predefined macros Frequently used routines provided by an application or
- language for the programmer.
-
- preprocessor A phase of the compiler that examines the source program for
- preprocessor statements, which are then executed, resulting in the
- alteration of the source program.
-
- primary expression Literals, names, and names qualified by the :: (scope
- resolution) operator.
-
- private Pertaining to a class member that is accessible only to member
- functions and friends of that class.
-
- profiling The process of generating a statistical analysis of a program that
- shows processor time and the percentage of program execution time
- used by each procedure in the program.
-
- protected Pertaining to a class member that is only accessible to member
- functions and friends of that class, or to member functions and
- friends of classes derived from that class.
-
- prototype A function declaration or definition that includes both the return
- type of the function and the types of its arguments.
-
- public Pertaining to a class member that is accessible to all functions.
-
- pure virtual function A virtual function that has a function initializer of
- the form = 0;.
-
-
- ΓòÉΓòÉΓòÉ <hidden> Q ΓòÉΓòÉΓòÉ
-
- qualified name Used to qualify a nonclass type name such as a member by its
- class name.
-
-
- ΓòÉΓòÉΓòÉ <hidden> R ΓòÉΓòÉΓòÉ
-
- reference class A class that links a concrete class to an abstract class.
- Reference classes make polymorphism possible with the Collection
- Classes.
-
- register storage class specifier A specifier that indicates to the compiler
- within a block scope data definition, or a parameter declaration,
- that the object being described will be heavily used.
-
- reentrant The attribute of a program or routine that allows the same copy of a
- program or routine to be used concurrently by two or more tasks.
-
- return A language construct that ends an execution sequence in a procedure.
-
-
- ΓòÉΓòÉΓòÉ <hidden> S ΓòÉΓòÉΓòÉ
-
- scalar An arithmetic object, or a pointer to an object of any type.
-
- scope That part of a source program in which an object is defined and
- recognized.
-
- scope operator (::) An operator that defines the scope for the argument on the
- right. If the left argument is blank, the scope is global; if the
- left argument is a class name, the scope is within that class. Also
- called a scope resolution operator.
-
- signal
-
- 1. A condition that may or may not be reported during program
- execution. For example, SIGFPE is the signal used to represent
- erroneous arithmetic operations such as a division by zero.
-
- 2. A mechanism by which a process may be notified of, or affected
- by, an event occurring in the system. Examples of such events
- include hardware exceptions and specific actions by processes.
- The term signal is also used to refer to the event itself.
- X/Open. ISO.1.
-
- 3. In AIX operating system operations, a method of interprocess
- communication that simulates software interrupts. IBM.
-
- signal handler A function to be called when the signal is reported.
-
- source file A file that contains source statements for such items as
- high-level language programs and data description specifications.
- IBM.
-
- source program A set of instructions written in a programming language that
- must be translated to machine language before the program can be
- run. IBM.
-
- specifiers Used in declarations to indicate storage class, fundamental data
- type and other properties of the object or function being declared.
-
- stack A data structure in which new elements are added to and removed from
- the top of the structure. A stack is characterized by
- Last-In-First-Out (LIFO) behavior.
-
- stack storage Synonym for automatic storage.
-
- standard error An output stream usually intended to be used for diagnostic
- messages.
-
- standard input An input stream usually intended to be used for primary data
- input. Standard input comes from the keyboard unless redirection or
- piping is used, in which case standard input can be from a file or
- the output from another command.
-
- standard output An output stream usually intended to be used for primary data
- output. X/Open. When programs are run interactively, standard
- output usually goes to the display unless redirection or piping is
- used, in which case standard output can go to a file or to another
- command.
-
- statement An instruction that ends with the character ; (semicolon) or several
- instructions that are surrounded by the characters { and }.
-
- static A keyword used for defining the scope and linkage of variables and
- functions. For internal variables, the variable has block scope and
- retains its value between function calls. For external values, the
- variable has file scope and retains its value within the source
- file. For class variables, the variable is shared by all objects of
- the class and retains its value within the entire program.
-
- storage class specifier One of: auto, register, static, or extern.
-
- stream
-
- 1. A continuous stream of data elements being transmitted, or
- intended for transmission, in character or binary-digit form,
- using a defined format.
-
- 2. A file access object that allows access to an ordered sequence
- of characters, as described by the ISO C standard. A stream
- provides the additional services of user-selectable buffering
- and formatted input and output.
-
- stream buffer A stream buffer is a buffer between the ultimate consumer,
- ultimate producer, and the I/O Stream Library functions that format
- data. It is implemented in the I/O Stream Library by the streambuf
- class and the classes derived from streambuf.
-
- string A contiguous sequence of characters.
-
- string literal Zero or more characters enclosed in double quotation marks.
-
- structure A construct that contains an ordered group of data objects. Unlike
- an array, the data objects within a structure can have varied data
- types.
-
- structure tag The identifier that names a structure data type.
-
- subscript One or more expressions, each enclosed in brackets, that follow an
- array name. A subscript refers to an element in an array.
-
- subsystem A secondary or subordinate system, usually capable of operating
- independently of or asynchronously with, a controlling system. ISO
- Draft.
-
- switch statement A C or C++ language statement that causes control to be
- transferred to one of several statements depending on the value of
- an expression.
-
-
- ΓòÉΓòÉΓòÉ <hidden> T ΓòÉΓòÉΓòÉ
-
- template A family of classes or functions where the code remains invariant
- but operates with variable types.
-
- template class A class instance generated by a class template.
-
- template function A function generated by a function template.
-
- this A C++ keyword that identifies a special type of pointer in a member
- function, one that references the class object with which the member
- function was invoked.
-
- thread
-
- 1. The smallest unit or path of execution within a process. IBM.
-
- 2. A piece of executing code.
-
- 3. In Windows, each thread is allocated its own stack from the
- owning process' 4-GB address space, and each one has its own
- set of processor registers, called the thread's context.
-
- throw expression An argument to the C++ exception being thrown.
-
- token The smallest independent unit of meaning of a program as defined
- either by a parser or a lexical analyzer. A token can contain data,
- a language keyword, an identifier, or other parts of language
- syntax.
-
- try block
-
- 1. A block in which a known C++ exception is passed to a handler.
-
- 2.
-
- type The description of the data and the operations that can be performed
- on or by the data. See also data type.
-
- type definition A definition of a name for a data type. IBM.
-
- type balancing A conversion that makes both operands have the same data type.
- If the operands do not have the same size data type, the compiler
- converts the value of the operand with the smaller type to a value
- having the larger type.
-
- type specifier Used to indicate the data type of an object or function being
- declared.
-
-
- ΓòÉΓòÉΓòÉ <hidden> U ΓòÉΓòÉΓòÉ
-
- unary expression An expression that contains one operand.
-
- undefined behavior Referring to a program or function that may produce
- erroneous results without warning because of its use of an
- indeterminate value, or because of erroneous program constructs or
- erroneous data.
-
- union
-
- 1. Structures that can contain different types of objects at
- different times. Only one of the member objects can be stored
- in a union at any time. IBM.
-
- 2. Given the sets A and B, all elements of A, B, or both A and B.
-
- union tag The identifier that names a union data type.
-
-
- ΓòÉΓòÉΓòÉ <hidden> V ΓòÉΓòÉΓòÉ
-
- variable In programming languages, a language object that may take different
- values, one at a time. The values of a variable are usually
- restricted to a certain data type. ISO-JTC1.
-
- virtual function A function of a class that is declared with the keyword
- virtual. The implementation that is executed when you make a call to
- a virtual function depends on the type of the object for which it is
- called. This is determined at run time.
-
- visible Visibility of identifiers is based on scoping rules and is
- independent of access.
-
- volatile An attribute of a data object that indicates the object is
- changeable beyond the control or detection of the compiler. Any
- expression referring to a volatile object is evaluated immediately,
- for example, assignments.
-
-
- ΓòÉΓòÉΓòÉ <hidden> W ΓòÉΓòÉΓòÉ
-
- white space Space characters, tab characters, form feed characters, and
- new-line characters.
-
- wide character A character whose range of values can represent distinct codes
- for all members of the largest extended character set specified
- among the supporting locales.
-
- Win32 The name of a 32-bit application programming interface (API).
-
- See also Win32 API.
-
- Win32 API
-
- 1. A set of Win32 functions that can be called from source code.
-
- 2. A 32-bit version of the 16-bit Windows 3.1 API (native to
- Windows NT).
-
- See also Win32.
-
- Windows NT A platform that the Win32 API is implemented on. It is a portable,
- high-end operating system, which can run several different types of
- applications simultaneously. It is the only Win32 platform for
- machine architectures based on processors other than the x86, and it
- supports multiple processors.
-
- See also Win32 API.
-
- word boundary Any storage position at which data must be aligned for certain
- processing operations. The halfword boundary must be divisible by 2;
- the fullword boundary by 4; and the doubleword boundary by 8. IBM.
-
- working directory
-
- 1. Synonym for current working directory.
-
- 2. The directory where files that are copied or dragged into the
- project are stored. Actions are also executed in this
- directory, so this directory is where many output files are
- placed.
-
- write
-
- 1. To output characters to a file, such as standard output or
- standard error. Unless otherwise stated, standard output is the
- default output destination for all uses of the term write.
- X/Open.
-
- 2. To make a permanent or transient recording of data in a storage
- device or on a data medium. ISO-JTC1. American National
- Standard for Information Systems.
-