0% found this document useful (0 votes)
254 views480 pages

C CPP Reference Manual

c++

Uploaded by

mahcimoi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
254 views480 pages

C CPP Reference Manual

c++

Uploaded by

mahcimoi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 480

OS/390



C/C++
Language Reference

SC09-2360-05

OS/390



C/C++
Language Reference

SC09-2360-05

Note!
Before using this information and the product it supports, be sure to read the information in Notices on page 411.

Sixth Edition (September 2000)


This edition applies to Version 2 Release 10 Modification 0 of OS/390 C/C++ (5647-A01) and to all subsequent
releases and modifications until otherwise indicated in new editions. This edition replaces SC09-2360-04. Make sure
that you use the correct edition for the level of the program listed above. Also, ensure that you apply all necessary
PTFs for the program.
Technical changes in the text since the last release of this book are indicated by a vertical line (|) to the left of the
change.
Order publications through your IBM representative or the IBM branch office serving your location. Publications are
not stocked at the address below. Note that the OS/390 C/C++ publications are available through the OS/390 Library
page at: http://www.ibm.com/s390/os390/bkserv/
IBM welcomes your comments. You can send your comments in any one of the following methods:
v Electronically to the network ID listed below. Be sure to include your entire network address if you want a reply.
Internet: [email protected]
IBMLink: toribm(torrcf)
v By FAX, use the following number:
United States and Canada: (416) 448-6161
Other countries: (+1) 416-448-6161
v By mail, to the following address:
IBM Canada Ltd. Laboratory
Information Development
2G/KB7/1150/TOR
1150 Eglinton Avenue East
Toronto, Ontario, Canada M3C 1H7
If you send comments, include the title and order number of this book, and the page number or topic related to your
comment. When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information
in any way it believes appropriate without incurring any obligation to you.
Copyright International Business Machines Corporation 1996, 2000. All rights reserved.
US Government Users Restricted Rights Use, duplication or disclosure restricted by GSA ADP Schedule Contract
with IBM Corp.

Contents
Part 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 1. About This Book . . . . . . .
Who Should Use This Book . . . . . . .
A Note about Examples . . . . . . . . .
IBM OS/390 C/C++ and Related Publications .
Hardcopy Books . . . . . . . . . . . .
PDF Books . . . . . . . . . . . . . .
Softcopy Books . . . . . . . . . . . .
Softcopy Examples . . . . . . . . . . .
OS/390 C/C++ on the World Wide Web . . .
How to Read the Syntax Diagrams . . . .

|
|

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

. 3
. 3
. 3
. 4
. 8
. 8
. 9
. 9
. . . . . . . . . . . . . 10
. . . . . . . . . . . . . 10

Chapter 2. About IBM OS/390 C/C++ . . . . . . . . . .


Changes for Version 2 Release 10 . . . . . . . . . . .
OS/390 Language Environment Downward Compatibility . .
The C/C++ Compilers . . . . . . . . . . . . . . . .
The C Language . . . . . . . . . . . . . . . . .
The C++ Language . . . . . . . . . . . . . . . .
Common Features of the OS/390 C and C++ Compilers. . .
OS/390 C Compiler Specific Features . . . . . . . . .
OS/390 C++ Compiler Specific Features . . . . . . . .
Utilities . . . . . . . . . . . . . . . . . . . . . .
Class Libraries . . . . . . . . . . . . . . . . . . .
Class Library Source. . . . . . . . . . . . . . . .
The Debug Tool . . . . . . . . . . . . . . . . . .
IBM C/C++ Productivity Tools for OS/390 . . . . . . . . .
OS/390 Language Environment . . . . . . . . . . . . .
The Program Management Binder . . . . . . . . . . . .
OS/390 UNIX System Services (OS/390 UNIX) . . . . . . .
OS/390 C/C++ Applications with OS/390 UNIX C/C++ Functions
Input and Output . . . . . . . . . . . . . . . . . .
I/O Interfaces . . . . . . . . . . . . . . . . . .
File Types. . . . . . . . . . . . . . . . . . . .
Additional I/O Features . . . . . . . . . . . . . . .
The System Programming C Facility . . . . . . . . . . .
Interaction with Other IBM Products . . . . . . . . . . .
Additional Features of OS/390 C/C++ . . . . . . . . . .

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

13
13
14
15
15
15
15
17
17
18
18
19
19
20
20
21
22
24
24
24
25
25
26
26
27

Part 2. The C and C++ Languages . . . . . . . . . . . . . . . . . . . . . . 31


Chapter 3. Introduction to C and C++ .
Overview of the C Language . . . . .
C Source Programs . . . . . . . .
CBC3RAAA - example C program . .
C Source Files . . . . . . . . . .
CBC3RAAB - Source File 1 . . . .
CBC3RMAX - Source file 2 . . . .
Program Execution . . . . . . . .
Scope in C . . . . . . . . . . .
Block Scope . . . . . . . . . .
Function Scope. . . . . . . . .
Copyright IBM Corp. 1996, 2000

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

33
33
34
34
35
35
36
36
37
37
37

iii

iv

File Scope . . . . . . . . . . . . . . . .
Function Prototype Scope . . . . . . . . . . .
Example of Scope in C . . . . . . . . . . . .
Related Information . . . . . . . . . . . . .
Program Linkage . . . . . . . . . . . . . . .
Internal Linkage . . . . . . . . . . . . . .
External Linkage . . . . . . . . . . . . . .
No Linkage . . . . . . . . . . . . . . . .
Storage Duration . . . . . . . . . . . . . . .
Name Spaces . . . . . . . . . . . . . . . .
Related Information . . . . . . . . . . . . .
Command-Line Arguments . . . . . . . . . . .
Under OS/390 Batch . . . . . . . . . . . . .
Under IMS . . . . . . . . . . . . . . . .
Under CICS . . . . . . . . . . . . . . . .
Under TSO Command . . . . . . . . . . . .
Under TSO Call . . . . . . . . . . . . . .
Under OS/390 UNIX Shell . . . . . . . . . . .
Related Information . . . . . . . . . . . . .
Overview of the C++ Language . . . . . . . . . .
C++ Support for Object-Oriented Programming . . . .
Data Abstraction . . . . . . . . . . . . . .
Encapsulation . . . . . . . . . . . . . . .
Inheritance . . . . . . . . . . . . . . . .
Dynamic Binding and Polymorphism . . . . . . .
Other Features of C++ . . . . . . . . . . . .
C++ Programs . . . . . . . . . . . . . . . .
CBC3X02D . . . . . . . . . . . . . . . .
Scope in C++ . . . . . . . . . . . . . . . .
Local Scope . . . . . . . . . . . . . . . .
Function Scope. . . . . . . . . . . . . . .
File Scope . . . . . . . . . . . . . . . .
Class Scope . . . . . . . . . . . . . . . .
Simple C++ Input and Output . . . . . . . . . .
CBC3X02F . . . . . . . . . . . . . . . .
Output (cout, cerr, and clog) . . . . . . . . . .
Input (cin) . . . . . . . . . . . . . . . . .
Linkage Specifications Linking to non-C++ Programs .
CBC3X02J . . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

37
37
37
38
38
39
39
40
40
40
41
41
41
42
42
42
42
42
43
43
43
43
44
44
44
45
45
47
47
47
48
48
48
48
49
49
50
50
51

Chapter 4. Lexical Elements of C and C++ .


Tokens . . . . . . . . . . . . . . .
Source Program Character Set . . . . . .
Trigraph Sequences . . . . . . . . .
Digraph Characters . . . . . . . . .
Additional Keywords (C++ only). . . . .
Comments . . . . . . . . . . . . .
C++ Comments. . . . . . . . . . .
Identifiers . . . . . . . . . . . . . .
Special Characters in Identifiers . . . .
Case Sensitivity in Identifiers . . . . . .
Significant Characters in Identifiers . . .
Keywords . . . . . . . . . . . . .
OS/390 C/C++ External Name Mapping. .
OS/390 Long Name Support . . . . . .
Constants . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

53
53
53
54
55
56
56
58
58
58
59
59
59
60
60
61

OS/390 V2R10.0 C/C++ Language Reference

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Integer Constants . . . . .
Floating-Point Constants . .
Fixed-Point Decimal Constants
Character Constants . . . .
String Literals . . . . . .
Escape Sequences . . . .

. . . .
. . . .
(C Only)
. . . .
. . . .
. . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

Chapter 5. Declarations . . . . . . . .
Declarations Overview . . . . . . . . .
Block Scope Data Declarations . . . . . .
Initialization . . . . . . . . . . . .
Storage . . . . . . . . . . . . .
Related Information . . . . . . . . .
File Scope Data Declarations . . . . . .
Initialization . . . . . . . . . . . .
Storage . . . . . . . . . . . . .
Related Information . . . . . . . . .
Objects. . . . . . . . . . . . . . .
Storage Class Specifiers . . . . . . . .
auto Storage Class Specifier . . . . . .
extern Storage Class Specifier . . . . .
register Storage Class Specifier. . . . .
static Storage Class Specifier . . . . .
typedef . . . . . . . . . . . . . . .
Examples of typedef Declarations . . . .
Related Information . . . . . . . . .
Type Specifiers . . . . . . . . . . . .
Characters . . . . . . . . . . . .
Floating-Point Variables. . . . . . . .
Fixed-Point Decimal Data Types (C Only) .
Integer Variables . . . . . . . . . .
Enumerations . . . . . . . . . . .
Pointers . . . . . . . . . . . . .
void Type . . . . . . . . . . . .
Arrays. . . . . . . . . . . . . .
Structures . . . . . . . . . . . .
Unions . . . . . . . . . . . . .
Declarators . . . . . . . . . . . .
Initializers . . . . . . . . . . . .
C/C++ Data Mapping . . . . . . . .
C++ Function Specifiers . . . . . . .
C++ References . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

. 71
. 71
. 72
. 73
. 73
. 73
. 73
. 74
. 74
. 74
. 74
. 74
. 75
. 77
. 83
. 83
. 85
. 86
. 86
. 87
. 87
. 88
. 89
. 90
. 91
. 95
. 100
. 101
. 107
. 114
. 121
. 129
. 131
. 131
. 131

Chapter 6. Expressions and Operators . .


Operator Precedence and Associativity . .
Examples of Expressions and Precedence
Operands . . . . . . . . . . . . .
lvalues . . . . . . . . . . . . . .
Examples of lvalues . . . . . . . .
Type-based Aliasing . . . . . . . .
Related Information . . . . . . . . .
Primary Expressions . . . . . . . . .
C++ Scope Resolution Operator (::) . . .
Parenthesized Expressions ( ) . . . .
Constant Expressions . . . . . . . .
Function Calls ( ) . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

Contents

62
63
65
65
66
68

133
133
135
135
136
136
136
137
137
138
138
139
140

Array Subscript [ ] (Array Element Specification)


Dot Operator (.) . . . . . . . . . . . .
Arrow Operator (>) . . . . . . . . . .
Unary Expressions . . . . . . . . . . . .
Increment (++) . . . . . . . . . . . .
Decrement () . . . . . . . . . . . .
Unary Plus (+) . . . . . . . . . . . .
Unary Minus () . . . . . . . . . . . .
Logical Negation (!) . . . . . . . . . . .
Bitwise Negation (). . . . . . . . . . .
Address (&) . . . . . . . . . . . . .
Indirection (*) . . . . . . . . . . . . .
Cast Expressions . . . . . . . . . . .
sizeof (Size of an Object) . . . . . . . .
digitsof and precisionof (C Only) . . . . . .
C++ new Operator . . . . . . . . . . .
C++ delete Operator . . . . . . . . . .
C++ throw Expressions . . . . . . . . .
Binary Expressions . . . . . . . . . . . .
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 (.* >*) . .
Conditional Expressions . . . . . . . . . .
Type of Conditional C Expressions . . . . .
Type of Conditional C++ Expressions . . . .
Examples of Conditional Expressions . . . .
Assignment Expressions . . . . . . . . . .
Simple Assignment (=) . . . . . . . . .
Compound Assignment . . . . . . . . .
Comma Expression (,). . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

141
142
142
142
143
143
144
144
144
144
145
145
146
146
148
148
151
152
152
153
153
153
154
154
154
155
156
157
158
158
159
160
160
161
162
162
162
163
163
164
165

Chapter 7. Implicit Type Conversions


Integral Promotions . . . . . . . .
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 . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

167
167
167
168
168
168
168
169
169
169
170
170

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

Chapter 8. Functions . . . . . . . . . . . . . . . . . . . . . . 173

vi

OS/390 V2R10.0 C/C++ Language Reference

Functions Overview. . . . . . . . .
C++ Enhancements to C Functions . . .
Function Declarations . . . . . . . .
C Function Declarations . . . . . .
C++ Function Declarations . . . . .
Examples of Function Declarations . .
Function Definitions. . . . . . . .
Related Information . . . . . . . .
The main() Function . . . . . . . .
Arguments to main . . . . . . . .
Example of Arguments to main . . .
Calling Functions and Passing Arguments
Passing Arguments in C++ . . . . .
Examples of Calling Functions. . . .
Passing Arguments by Reference . .
Default Arguments in C++ Functions . .
CBC3X06B . . . . . . . . . . .
Restrictions on Default Arguments . .
Evaluating Default Arguments . . . .
Function Return Values . . . . . . .
Using References as Return Types . .
Pointers to Functions . . . . . . . .
C++ Inline Functions . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

173
173
174
174
174
176
178
183
183
183
184
184
186
186
188
189
189
190
190
191
192
192
194

Chapter 9. Statements . . . . . . . .
Labels . . . . . . . . . . . . . .
Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
Block . . . . . . . . . . . . . . .
Initialization within Block Statements . .
Example . . . . . . . . . . . . .
Related Information . . . . . . . . .
break . . . . . . . . . . . . . . .
Restrictions. . . . . . . . . . . .
Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
continue . . . . . . . . . . . . . .
Restrictions. . . . . . . . . . . .
Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
do . . . . . . . . . . . . . . . .
Example . . . . . . . . . . . . .
Related Information . . . . . . . . .
Expression . . . . . . . . . . . . .
Examples . . . . . . . . . . . .
Resolving Ambiguous Statements in C++ .
for . . . . . . . . . . . . . . . .
Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
goto . . . . . . . . . . . . . . .
Example . . . . . . . . . . . . .
if . . . . . . . . . . . . . . . .
Examples . . . . . . . . . . . .
null . . . . . . . . . . . . . . . .
Example . . . . . . . . . . . . .
return . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

195
195
195
195
196
196
197
197
197
198
198
199
199
199
200
201
201
201
202
202
202
202
203
204
205
206
206
207
207
208
208
208

Contents

vii

Value of a return Expression and Function


Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
switch . . . . . . . . . . . . . . .
Restrictions . . . . . . . . . . . .
Examples . . . . . . . . . . . .
Related Information . . . . . . . . .
while . . . . . . . . . . . . . . .
Example . . . . . . . . . . . . .
Related Information . . . . . . . . .

Value
. .
. .
. .
. .
. .
. .
. .
. .
. .

Chapter 10. Preprocessor Directives . . . .


Preprocessor Overview . . . . . . . . . .
Preprocessor Directive Format. . . . . . . .
Phases of Preprocessing. . . . . . . . . .
Macro Definition and Expansion (#define) . . .
Object-Like Macros . . . . . . . . . . .
Function-Like Macros . . . . . . . . . .
Scope of Macro Names (#undef) . . . . . . .
Examples of #undef Directives. . . . . . .
Single Number Sign Operator (#). . . . . . .
Examples of the # Operator. . . . . . . .
Related Information . . . . . . . . . . .
Macro Concatenation with the ## Operator . . .
Double Number Sign Operator (##) . . . . .
Preprocessor Error Directive (#error) . . . . .
Related Information . . . . . . . . . . .
File Inclusion (#include) . . . . . . . . . .
Predefined Macro Names . . . . . . . . .
ANSI/ISO Standard Predefined Macro Names .
OS/390 C/C++ Predefined Macro Names . . .
Examples of Predefined Macros . . . . . .
Conditional Compilation Directives . . . . . .
#if, #elif . . . . . . . . . . . . . . .
#ifdef . . . . . . . . . . . . . . . .
#ifndef . . . . . . . . . . . . . . .
#else . . . . . . . . . . . . . . . .
#endif . . . . . . . . . . . . . . . .
Examples of Conditional Compilation Directives
Line Control (#line) . . . . . . . . . . . .
Example of #line Directives . . . . . . . .
Null Directive (#) . . . . . . . . . . . . .
Pragma Directives (#pragma) . . . . . . . .
Restrictions on #pragma Directives . . . . .
IPA Considerations . . . . . . . . . . .
chars . . . . . . . . . . . . . . . .
checkout. . . . . . . . . . . . . . .
comment . . . . . . . . . . . . . .
convlit. . . . . . . . . . . . . . . .
csect . . . . . . . . . . . . . . . .
define (C++ Only) . . . . . . . . . . .
disjoint (C Only) . . . . . . . . . . . .
environment (C Only) . . . . . . . . . .
export . . . . . . . . . . . . . . . .
filetag . . . . . . . . . . . . . . . .
hdrstop . . . . . . . . . . . . . . .

viii

OS/390 V2R10.0 C/C++ Language Reference

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

209
209
210
210
211
212
214
214
214
214

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

215
215
216
216
217
217
218
221
221
221
222
222
222
223
223
224
224
225
225
226
232
233
234
235
235
236
236
236
237
238
238
238
241
242
243
243
244
245
246
247
247
248
248
249
249

implementation (C++ Only) . . . .


info (C++ Only) . . . . . . . .
inline (C Only) - also see noinline .
isolated_call . . . . . . . . .
langlvl. . . . . . . . . . . .
leaves. . . . . . . . . . . .
linkage . . . . . . . . . . .
longname . . . . . . . . . .
map . . . . . . . . . . . .
margins . . . . . . . . . . .
noinline (C and C++) - also see inline
options (C Only) . . . . . . . .
option_override . . . . . . . .
pack . . . . . . . . . . . .
page (C Only) . . . . . . . . .
pagesize (C Only) . . . . . . .
priority (C++ Only) . . . . . . .
reachable . . . . . . . . . .
runopts . . . . . . . . . . .
sequence . . . . . . . . . .
skip (C Only) . . . . . . . . .
strings . . . . . . . . . . .
subtitle (C Only) . . . . . . . .
target (C Only) . . . . . . . .
title (C Only) . . . . . . . . .
variable . . . . . . . . . . .
wsizeof . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

250
250
251
253
254
256
256
258
259
261
262
263
264
266
267
267
267
268
268
270
271
271
271
272
273
273
273

Part 3. C++ Language Elements . . . . . . . . . . . . . . . . . . . . . . . 275


Chapter 11. C++ Classes . . .
C++ Classes Overview . . . .
Classes and Structures . . .
Aggregate Classes . . . . .
Declaring Class Objects . . . .
Class Names . . . . . . .
Using Class Objects . . . .
Scope of Class Names . . . .
CBC3X10E . . . . . . . .
Incomplete Class Declarations.
Nested Classes . . . . . .
Local Classes . . . . . . .
Local Type Names . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

277
277
277
278
278
279
280
282
282
282
283
284
285

Chapter 12. C++ Class Members and Friends


Class Member Lists. . . . . . . . . . .
Data Members . . . . . . . . . . . .
Class-Type Class Members . . . . . . . .
Member Functions . . . . . . . . . . .
const and volatile Member Functions . . .
Virtual Member Functions . . . . . . .
Special Member Functions . . . . . . .
Inline Member Functions . . . . . . . .
Member Function Templates . . . . . .
Member Scope . . . . . . . . . . . .
CBC3X11A . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.

287
287
288
288
289
289
289
290
290
290
291
291

Contents

ix

Pointers to Members . . . . . .
CBC3X11B . . . . . . . . .
The this Pointer . . . . . . . .
CBC3X11C . . . . . . . . .
CBC3X11D . . . . . . . . .
Static Members . . . . . . . .
Using the Class Access Operators
Static Data Members . . . . .
Static Member Functions . . . .
Member Access . . . . . . . .
Classes and Access Control . .
Access Specifiers . . . . . .
Friends . . . . . . . . . . .
CBC3X11I . . . . . . . . .
CBC3X11J . . . . . . . . .
Friend Scope . . . . . . . .
Friend Access . . . . . . . .

. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
with Static
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .

. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
Members
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

292
293
293
294
294
295
296
297
299
299
300
300
301
302
302
303
304

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

305
305
305
305
306
306
307
308
308
309
309
310
311
311
311
312
312
313
313
314
314
316

Chapter 14. Special C++ Member Functions .


Constructors and Destructors Overview . . .
Constructors . . . . . . . . . . . . .
Default Constructors . . . . . . . . .
Copy Constructors . . . . . . . . . .
Construction Order of Class Objects . . .
Explicitly Constructing Objects . . . . . .
Destructors . . . . . . . . . . . . . .
Free Store . . . . . . . . . . . . . .
Temporary Objects . . . . . . . . . . .
Related Information . . . . . . . . . .
User-Defined Conversions . . . . . . . .
Conversion by Constructor . . . . . . .
Conversion Functions . . . . . . . . .
Initialization by Constructor . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

317
317
318
318
318
319
320
320
322
324
325
325
326
326
327

Chapter 13. C++ Overloading . . . . .


Overloading Functions. . . . . . . . .
CBC3X12A . . . . . . . . . . . .
Declaration Matching . . . . . . . .
Restrictions on Overloaded Functions . .
Argument Matching in Overloaded Functions
Sequence of Argument Conversions . .
Trivial Conversions . . . . . . . . .
Overloading Operators . . . . . . . .
CBC3X12B . . . . . . . . . . . .
General Rules for Overloading Operators.
Operands of Overloaded Operators . . .
Restrictions on Overloaded Operators . .
Overloading Unary Operators . . . . . .
Overloading Binary Operators . . . . . .
Special Overloaded Operators . . . . . .
Overloaded Assignment . . . . . . .
Overloaded Function Calls . . . . . .
Overloaded Subscripting . . . . . . .
Overloaded Class Member Access . . .
Overloaded Increment and Decrement . .
Overloaded new and delete . . . . . .

OS/390 V2R10.0 C/C++ Language Reference

Explicit Initialization . . . . . . . . . .
Initializing Base Classes and Members . .
Construction Order of Derived Class Objects
Copying Class Objects . . . . . . . . .
Copy Restrictions . . . . . . . . . .
Copy by Assignment . . . . . . . . .
Copy by Initialization . . . . . . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

327
329
330
331
331
331
332

Chapter 15. C++ Inheritance . . . . .


Inheritance Overview . . . . . . . .
Multiple Inheritance . . . . . . . .
The Inheritance Design Process . . .
Direct and Indirect Base Classes . . .
Polymorphism . . . . . . . . . .
Derivation . . . . . . . . . . . .
CBC3X14A . . . . . . . . . . .
CBC3X14B . . . . . . . . . . .
CBC3X14C . . . . . . . . . . .
Syntax of a Derived Class Declaration .
Inherited Member Access . . . . . .
Protected Members . . . . . . . .
Derivation Access of Base Classes . .
Access Declarations . . . . . . .
Access Resolution . . . . . . . .
Access Summary . . . . . . . .
Multiple Inheritance . . . . . . . . .
Virtual Base Classes . . . . . . .
Multiple Access . . . . . . . . .
Accessible Base Classes. . . . . .
Ambiguous Base Classes . . . . .
Virtual Functions . . . . . . . . . .
Ambiguous Virtual Function Calls. . .
Virtual Function Access . . . . . .
Abstract Classes . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

335
335
336
337
337
338
338
339
339
340
340
341
342
342
343
345
347
347
348
349
350
350
351
353
354
355

Chapter 16. C++ Templates . . . . . . . . .


Templates Overview . . . . . . . . . . . .
CBC3X15A . . . . . . . . . . . . . . .
Structuring Your Program Using Templates . . . .
File stack.h . . . . . . . . . . . . . . .
File stackdef.h . . . . . . . . . . . . .
Class Templates . . . . . . . . . . . . . .
Class Template Declarations and Definitions . .
Reference and Uniqueness . . . . . . . . .
Nontype Template Arguments . . . . . . . .
Explicitly Defined Template Classes . . . . . .
Function Templates . . . . . . . . . . . . .
Example of a Function Template . . . . . . .
Overloading Resolution for Template Functions .
Defining Template Functions . . . . . . . .
Explicitly Defined Template Functions . . . . .
Function Template Declarations and Definitions .
Differences between Class and Function Templates .
CBC3X15B . . . . . . . . . . . . . . .
Member Function Templates . . . . . . . . .
Friends and Templates . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

357
357
358
359
359
359
360
362
362
363
364
365
365
365
366
366
367
368
368
369
370

Contents

xi

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

Static Data Members and Templates . . . . . . . . . . . . . . . . 371


Chapter 17. C++ Exception Handling . . . . . . .
C++ Exception Handling Overview . . . . . . . . .
Formal and Informal Exception Handling . . . . . . .
Using Exception Handling . . . . . . . . . . . .
Transferring Control . . . . . . . . . . . . . .
CBC3X16A . . . . . . . . . . . . . . . . .
CBC3X16F . . . . . . . . . . . . . . . . .
Catching Exceptions . . . . . . . . . . . . .
Matching Exceptions Thrown and Exceptions Caught .
Order of Catching . . . . . . . . . . . . . .
Nested Try Blocks . . . . . . . . . . . . . .
Rethrowing an Exception. . . . . . . . . . . .
Using a Conditional Expression in a Throw Expression.
Constructors and Destructors in Exception Handling. . .
CBC3X16D . . . . . . . . . . . . . . . . .
Exception Specifications . . . . . . . . . . . . .
Exception Specification Syntax . . . . . . . . .
Empty Exception Specifications . . . . . . . . .
Functions without an Exception Specification . . . .
Other Exception Specifications . . . . . . . . .
Special Exception Handling Functions . . . . . . . .
unexpected() . . . . . . . . . . . . . . . .
terminate() . . . . . . . . . . . . . . . . .
set_unexpected() and set_terminate() . . . . . . .
Example of Using the Exception Handling Functions .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

373
373
374
374
376
376
377
378
379
379
379
380
381
382
383
384
384
385
385
385
386
386
386
386
387

Part 4. Appendixes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389


Appendix A. C and C++ Compatibility . . .
C++ Constructs Not Found in ANSI/ISO C . .
Constructs Found in Both C++ and ANSI/ISO C
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. . . . . .
Interactions with Other Products . . . . . .

xii

OS/390 V2R10.0 C/C++ Language Reference

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

391
391
391
391
392
392
392
392
392
393
393
393
393
393
393
393
394
394
394
394
394
394
394
395
395

Appendix B. Common Usage C Language Level . . . . . . . . . . . 397


Appendix C. Conforming to POSIX 1003.1

Appendix D. Supporting ANSI/ISO Standards


Implementation-Defined Behavior. . . . . .
Identifiers . . . . . . . . . . . . .
Characters . . . . . . . . . . . . .
String Conversion . . . . . . . . . .
Integers . . . . . . . . . . . . . .
Floating-Point . . . . . . . . . . . .
Arrays and Pointers. . . . . . . . . .
Registers . . . . . . . . . . . . .
Structures, Unions, Enumerations, Bit Fields
Declarators . . . . . . . . . . . . .
Statements . . . . . . . . . . . . .
Preprocessing Directives . . . . . . . .
Library Functions . . . . . . . . . .
Error Handling. . . . . . . . . . . .
Signals . . . . . . . . . . . . . .
Translation Limits . . . . . . . . . .
Streams, Records, and Files . . . . . .
Memory Management . . . . . . . . .
Environment . . . . . . . . . . . .
Localization. . . . . . . . . . . . .
Time . . . . . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

401
401
401
402
402
403
403
404
404
404
405
405
405
405
406
407
407
408
409
409
410
410

Notices . .
Programming
Trademarks.
Standards .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

411
412
412
413

Glossary

|
|
|
|

. . . . . . . . . . . . . 399

. . . . . . . .
Interface Information
. . . . . . . .
. . . . . . . .

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

. . . . . . . . . . . . . . . . . . . . . . . . . . 415

Bibliography . .
OS/390 . . . .
OS/390 C/C++ .
OS/390 Language
Assembler . . .
COBOL . . . .
PL/I . . . . .
VS FORTRAN. .
CICS . . . . .
DB2 . . . . .
IMS/ESA. . . .
QMF . . . . .
DFSMS . . . .
INDEX

.
.
.
.

. . . . .
. . . . .
. . . . .
Environment
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.
.
.

443
443
443
443
443
444
444
444
444
444
445
445
445

. . . . . . . . . . . . . . . . . . . . . . . . . . . 447

Contents

xiii

xiv

OS/390 V2R10.0 C/C++ Language Reference

Part 1. Introduction
This part describes how to use the OS/390 C/C++ Language Reference, and how
to find additional information in the OS/390 C/C++ library. This part introduces the
IBM OS/390 C/C++ product.
Chapter 1. About This Book
Describes how to use this book in relation to the OS/390 C/C++ information
library and related OS/390 documentation.
Chapter 2. About IBM OS/390 C/C++
Introduces the OS/390 C/C++ product and its key features, related OS/390
environments such as OS/390 UNIX System Services, and other OS/390
tools that are useful when using OS/390 C/C++.

Copyright IBM Corp. 1996, 2000

OS/390 V2R10.0 C/C++ Language Reference

Chapter 1. About This Book


This book describes the IBM C language and C++ language definitions which
comply with the POSIX and XPG4 standards, and which the OS/390 Language
Environment implements. Use this book if you are a programmer who needs to
understand the support that IBM OS/390 C/C++ provides.

Who Should Use This Book


This book is intended for programmers who will write C or C++ applications under
the OS/390 operating system. This book is a reference rather than a tutorial. It
assumes that you have some experience with writing C or C++ programs and are
familiar with the OS/390 operating system.

A Note about Examples


Examples that illustrate the use of the OS/390 C/C++ compiler use a simple style.
They are instructional examples, and do not attempt to minimize run time, conserve
storage, or check for errors. The examples do not demonstrate all the uses of C
and C++ language constructs. Some examples are only code fragments and will not
compile without additional code.

Copyright IBM Corp. 1996, 2000

IBM OS/390 C/C++ and Related Publications


This section summarizes the content of the IBM OS/390 C/C++ publications and
shows where to find related information in other publications.
Table 1. OS/390 C/C++ Publications
Book Title and Number

Key Sections/Chapters in the Book

OS/390 C/C++ Programming Guide,


SC09-2362

Guidance information for:


v C/C++ input and output
v Debugging OS/390 C programs that use input/output
v Using linkage specifications in C++
v Combining C and assembler
v Creating and using DLLs
v Using threads in an OS/390 UNIX application
v Reentrancy
v Using the decimal data type in C and C++
v Handling exceptions, error conditions, and signals
v Optimizing code
v Optimizing your C/C++ code with Interprocedural Analysis
v Network communications under OS/390 UNIX
v Interprocess communications using OS/390 UNIX
v Structuring a program that uses C++ templates
v Using environment variables
v Using System Programming C facilities
v Library functions for the System Programming C facilities
v Using runtime user exits
v Using the OS/390 C multitasking facility
v Using other IBM products with OS/390 C/C++ (CICS, CSP, DWS, DB2,
GDDM, IMS, ISPF, QMF)
v Internationalization: locales and character sets, code set conversion utilities,
mapping variant characters
v POSIX character set
v Code point mappings
v Locales supplied with OS/390 C/C++
v Charmap files supplied with OS/390 C/C++
v Examples of charmap and locale definition source files
v Converting code from coded character set IBM-1047
v Using built-in functions
v Programming considerations for OS/390 UNIX C/C++

OS/390 C/C++ Users Guide,


SC09-2361

Guidance information for:


v OS/390 C/C++ examples
v Compiler options
v Binder options and control statements
v Specifying OS/390 Language Environment runtime options
v Compiling, IPA Linking, binding, and running OS/390 C/C++ programs
v Using precompiled headers
v Utilities (Object Library, DLL Rename, CXXFILT, DSECT Conversion, Code
Set and Locale, ar and make, BPXBATCH)
v Diagnosing problems
v Cataloged procedures and REXX EXECs supplied by IBM
v Error messages and return codes

OS/390 V2R10.0 C/C++ Language Reference

Table 1. OS/390 C/C++ Publications (continued)


Book Title and Number

Key Sections/Chapters in the Book

OS/390 C/C++ Language Reference,


SC09-2360

Reference information for:


v The C and C++ languages
v Lexical elements of OS/390 C and OS/390 C++
v Declarations, expressions, and operators
v Implicit type conversions
v Functions and statements
v Preprocessor directives
v C++ classes, class members, and friends
v C++ overloading, special member functions, and inheritance
v C++ templates and exception handling
v OS/390 C and OS/390 C++ compatibility

OS/390 C/C++ Run-Time Library


Reference, SC28-1663

Reference information for:


v C header files
v C Library functions

OS/390 C Curses, SC28-1907

Reference information for:


v Curses concepts
v Key data types
v General rules for characters, renditions, and window properties
v General rules of operations and operating modes
v Use of macros
v Restrictions on block-mode terminals
v Curses functional interface
v Contents of headers
v The terminfo database

OS/390 C/C++ Compiler and


Run-Time Migration Guide,
SC09-2359

Guidance and reference information for:


v Common migration questions
v Application executable program compatibility
v Source program compatibility
v Input and output operations compatibility
v Class library migration considerations
v Changes between releases of OS/390
v C/370 to current compiler migration
v Other migration considerations

OS/390 C/C++ Reference Summary,


SX09-1313

Summary tables for:


v Character set, trigraphs, digraphs, and keywords
v Escape sequences, storage classes
v Predefined and derived types, type qualifiers
v Operator precedence, redirection symbols
v fprintf() format, type characters, and flag characters
v fscanf() format and type characters
v __amrc structure
v Hardware exceptions and signals
v Compiler return codes
v Compiler options
v #pragma directives
v Library functions
v Utilities

Chapter 1. About This Book

Table 1. OS/390 C/C++ Publications (continued)


Book Title and Number

Key Sections/Chapters in the Book

OS/390 C/C++ IBM Open Class


Library Users Guide, SC09-2363

Guidance information for:


v Using the Complex Mathematics Class Library: Review of complex
numbers, header files, constructing complex objects, mathematical
operators for complex, friend functions for complex, handling complex
mathematics errors
v Using the I/O Stream Class Library: Introduction, getting started, advanced
topics, and manipulators
v Using the Collection Class Library: Overview, instantiating and using,
element and key functions, tailoring a collection implementation,
polymorphic use of collections, support for notifications, exception handling,
tutorials, problem solving, compatibility with previous releases, thread safety
v Using the Application Support Class Library: Introduction, String classes,
Exception and Trace classes, Date and Time classes, controlling threads
and protecting data, the IBM Open Class* notification framework, Binary
Coded (Packed) Decimal classes

OS/390 C/C++ IBM Open Class


Library Reference, SC09-2364

Reference information for:


v Complex Mathematics Class Library
v I/O Stream Class Library
v Collection Class Library
v Application Support Class Library

Debug Tool Users Guide and


Reference, SC09-2137

Guidance and reference information for:


v Preparing to debug programs
v Debugging programs
v Using Debug Tool in different environments
v Language-specific information
v Debug Tool reference

APAR and BOOKS files (Shipped with Partitioned data set CBC.SCBCDOC on the product tape contains the
Program materials)
members, APAR and BOOKS, which provide additional information for using
the IBM OS/390 C/C++ licensed program, including:
v Isolating reportable problems
v Keywords
v Preparing an Authorized Program Analysis Report (APAR)
v Problem identification worksheet
v Maintenance on OS/390
v Late changes to OS/390 C/C++ publications
Note: For complete and detailed information on linking and running with OS/390 Language Environment and using
the OS/390 Language Environment runtime options, refer to OS/390 Language Environment Programming Guide,
SC28-1939. For complete and detailed information on using interlanguage calls, refer to OS/390 Language
Environment Writing Interlanguage Applications, SC28-1943.

The following table lists the OS/390 C/C++ and related publications. The table
groups the publications according to the tasks they describe.
Table 2. Publications by Task
Tasks

Books

Planning, preparing, and migrating to OS/390


C/C++

v OS/390 C/C++ Compiler and Run-Time Migration Guide,


SC09-2359
v OS/390 Language Environment Customization, SC28-1941
v OS/390 UNIX System Services Planning, SC28-1890
v OS/390 Planning for Installation, GC28-1726
v OS/390 Task Atlas, available on the OS/390 Library page on the
World Wide Web (http://www.ibm.com/s390/os390/bkserv/)

OS/390 V2R10.0 C/C++ Language Reference

Table 2. Publications by Task (continued)


Tasks

Books

Installing

v OS/390 Program Directory


v OS/390 Planning for Installation, GC28-1726
v OS/390 Language Environment Customization, SC28-1941

Coding programs

v
v
v
v
v
v
v

Coding and binding programs with


interlanguage calls

v
v
v
v

Compiling, binding, and running programs

v OS/390 C/C++ Users Guide, SC09-2361


v OS/390 Language Environment Programming Guide, SC28-1939
v OS/390 Language Environment Debugging Guide and Run-Time
Messages, SC28-1942
v OS/390 DFSMS Program Management, SC27-0806
v OS/390 Messages Database, available on the OS/390 Library page
on the World Wide Web (http://www.ibm.com/s390/os390/bkserv/)

Compiling and binding applications in the


OS/390 UNIX environment

v
v
v
v

OS/390
OS/390
OS/390
OS/390

Debugging programs

v
v
v
v
v
v

README file
Debug Tool Users Guide and Reference, SC09-2137
OS/390 C/C++ Users Guide, SC09-2361
OS/390 C/C++ Programming Guide, SC09-2362
OS/390 Language Environment Programming Guide, SC28-1939
OS/390 Language Environment Debugging Guide and Run-Time
Messages, SC28-1942
OS/390 UNIX System Services Messages and Codes, SC28-1908
OS/390 UNIX System Services Users Guide, SC28-1891
OS/390 UNIX System Services Command Reference, SC28-1892
OS/390 UNIX System Services Programming Tools, SC28-1904

OS/390 C/C++ Run-Time Library Reference, SC28-1663


OS/390 C/C++ Language Reference, SC09-2360
OS/390 C/C++ Reference Summary, SX09-1313
OS/390 C/C++ Programming Guide, SC09-2362
OS/390 Language Environment Concepts Guide, GC28-1945
OS/390 Language Environment Programming Guide, SC28-1939
OS/390 Language Environment Programming Reference,
SC28-1940
v OS/390 C/C++ IBM Open Class Library Users Guide, SC09-2363
v OS/390 C/C++ IBM Open Class Library Reference, SC09-2364
OS/390 C/C++ Programming Guide, SC09-2362
OS/390 C/C++ Language Reference, SC09-2360
OS/390 Language Environment Programming Guide, SC28-1939
OS/390 Language Environment Writing Interlanguage Applications,
SC28-1943
v OS/390 DFSMS Program Management, SC27-0806

v
v
v
v

C/C++ Users Guide, SC09-2361


UNIX System Services Users Guide, SC28-1891
UNIX System Services Command Reference, SC28-1892
DFSMS Program Management, SC27-0806

Using shells and utilities in the OS/390 UNIX


environment

v OS/390 C/C++ Users Guide, SC09-2361


v OS/390 UNIX System Services Command Reference, SC28-1892
v OS/390 UNIX System Services Messages and Codes, SC28-1908

Using sockets library functions in the OS/390


UNIX environment

v OS/390 C/C++ Run-Time Library Reference, SC28-1663

Chapter 1. About This Book

Table 2. Publications by Task (continued)


Tasks

Books

Porting a UNIX Application to OS/390

v OS/390 UNIX System Services Porting Guide


This guide contains useful information about supported header files
and C functions, sockets in an OS/390 UNIX environment, process
management, compiler optimization tips, and suggestions for
improving the applications performance after it has been ported.
The Porting Guide is available as a PDF file which you can
download, or as web pages which you can browse, at the following
web address: http://www.ibm.com/s390/unix/bpxa1por.html

Working in the OS/390 UNIX System Services v OS/390 UNIX System Services Parallel Environment: Operation
Parallel Environment
and Use, SC33-6697
v OS/390 UNIX System Services Parallel Environment: MPI
Programming and Subroutine Reference, SC33-6696

|
|
|

Performing diagnosis and submitting an


Authorized Program Analysis Report (APAR)

v OS/390 C/C++ Users Guide, SC09-2361


v CBC.SCBCDOC(APAR) on OS/390 C/C++ product tape

Tuning Large C/C++ Applications on OS/390


UNIX System Services

v IBM Redbook called Tuning Large C/C++ Applications on OS/390


UNIX System Services, which is available at:
http://www.redbooks.ibm.com/abstracts/sg245606.html

Quick reference

v OS/390 C/C++ Reference Summary, SX09-1313

Note: For information on using the prelinker, see the appendix on prelinking and linking OS/390 C/C++ programs in
OS/390 C/C++ Users Guide. As of Release 4, this appendix contains information that was previously in the chapter on
prelinking and linking OS/390 C/C++ programs in OS/390 C/C++ Users Guide. It also contains prelinker information
that was previously in OS/390 C/C++ Programming Guide.

Hardcopy Books
The following OS/390 C/C++ books are available in hardcopy:
v OS/390 C/C++ Run-Time Library Reference, SC28-1663
v OS/390 C/C++ Users Guide, SC09-2361
v OS/390 C/C++ Programming Guide, SC09-2362
v OS/390 C/C++ Reference Summary, SX09-1313
v OS/390 C/C++ IBM Open Class Library Users Guide, SC09-2363
v OS/390 C Curses, SC28-1907
v OS/390 C/C++ Compiler and Run-Time Migration Guide, SC09-2359
v Debug Tool Users Guide and Reference, SC09-2137
You can purchase these books on their own, or as part of a set. You receive
OS/390 C/C++ Compiler and Run-Time Migration Guide, SC09-2359 at no charge.
Feature code 8009 includes the remaining books.

PDF Books
All of the OS/390 C/C++ publications are supplied in PDF format. The books are
available on a CD-ROM called OS/390 PDF Library Collection, SK2T-6718. They
are also available at the following Web Site:
http://www.ibm.com/software/ad/c390/cmvsdocs.html

To read a PDF file, use the Adobe Acrobat Reader. If you do not have the Adobe
Acrobat Reader, you can download it for free from the Adobe Web Site:
http://www.adobe.com

OS/390 V2R10.0 C/C++ Language Reference

Softcopy Books
All of the OS/390 C/C++ publications (except for OS/390 C/C++ Reference
Summary) are available in softcopy book format. The books are available on the
tape that accompanies the OS/390 product, and on a CD-ROM called IBM Online
Library Omnibus Edition OS/390 Collection, SK2T-6700.
|
|
|

To read the softcopy books, use BookManager READ/MVS Version 1 Release 3


(5695-046) or the Library Reader for DOS, OS/2 or Windows supplied on the
CD-ROMs containing BookManager books.
If your system has BookManager Read installed, you can enter the command
BOOKMGR to start BookManager and display a list of books available to you. If you
know the name of the book that you want to view, you can use the OPEN
command to open the book directly.
Note: If your workstation does not have graphics capability, BookManager Read
cannot correctly display some characters, such as arrows and brackets.
You can also browse the books on the World Wide Web by clicking on "The Library"
link on the OS/390 home page. The web address for this page is:
http://www.ibm.com/s390/os390

Softcopy Examples
Most of the larger examples in the following books are available in
machine-readable form:
v OS/390 C/C++ Language Reference, SC09-2360
v OS/390 C/C++ Users Guide, SC09-2361
v OS/390 C/C++ Programming Guide, SC09-2362
v OS/390 C/C++ IBM Open Class Library Users Guide, SC09-2363
v OS/390 C/C++ IBM Open Class Library Reference, SC09-2364
In the following books, a label on an example indicates that the example is
distributed in softcopy. The label is the name of a member in the data sets
CBC.SCBCSAM or CBC.SCLBSAM. The labels have the form CBCxyyy or CLBxyyy, where
x refers to a publication:
v R and X refer to OS/390 C/C++ Language Reference, SC09-2360
v G refers to OS/390 C/C++ Programming Guide, SC09-2362
v U refers to OS/390 C/C++ Users Guide, SC09-2361
v A refers to OS/390 C/C++ IBM Open Class Library Users Guide, SC09-2363
Examples labelled as CBCxyyy appear in OS/390 C/C++ Language Reference,
OS/390 C/C++ Programming Guide, and OS/390 C/C++ Users Guide. Examples
labelled as CLBxyyy appear in OS/390 C/C++ IBM Open Class Library Users
Guide.
An exception applies to the example names for the Collection Class Library which
do not follow a naming convention. These examples are in OS/390 C/C++ IBM
Open Class Library Reference, SC09-2364.

Chapter 1. About This Book

OS/390 C/C++ on the World Wide Web


Additional information on OS/390 C/C++ is available on the World Wide Web on the
OS/390 C/C++ home page at:
http://www.ibm.com/software/ad/c390

This page contains late-breaking information about the OS/390 C/C++ product,
including the compiler, the class libraries, and utilities. It also contains a tutorial on
the source level interactive debugger. There are links to other useful information,
such as the OS/390 C/C++ information library and the libraries of other OS/390
elements that are available on the Web. The OS/390 C/C++ home page also
contains samples that you can download, and links to other related Web sites.

How to Read the Syntax Diagrams


This book describes the syntax for commands, directives, and statements, using the
following structure:
v Read the syntax diagrams from left to right, from top to bottom, following the path
of the line.
A double right arrowhead indicates the beginning of a command, directive, or
statement. A single right arrowhead indicates that it is continued on the next line.
In the following diagrams, "statement" represents a command, directive, or
statement.
%% statement

%&

v Required items are on the horizontal line (the main path).


%% statement required_item

%&

v Optional items are below the main path.


%% statement

optional_item

%&

v If you can choose from two or more items, they are vertical in a stack.
If you must choose one of the items, one item of the stack is on the main path.
%% statement

required_choice1
required_choice2

%&

If choosing one of the items is optional, the entire stack is below the main path.
%% statement

optional_choice1
optional_choice2

v An arrow that returns to the left above the main line indicates an item that you
can repeat.

10

OS/390 V2R10.0 C/C++ Language Reference

%&

%% statement '

repeatable_item

%&

A repeat arrow above a stack indicates that you can make more than one choice
from the stacked items, or repeat a single choice.
v Keywords are not italicized, and should be entered exactly as shown (for
example, pragma). You must spell keywords exactly as shown in the syntax
diagram. Variables are in lowercase italics (in hardcopy), for example, identifier.
They represent user-supplied names or values.
v If the syntax diagram shows punctuation marks, parentheses, arithmetic
operators, or other nonalphanumeric characters, you must enter them as part of
the syntax.
Note: You do not always require the white space between tokens. You should,
however, include at least one blank space between tokens unless otherwise
specified.
The following syntax diagram example shows the syntax for the #pragma comment
directive.
%%

% (

(1)

(5)

(2)

pragma

(6)
compiler
date
timestamp
copyright
user

(3)

comment

(4)

(7)

"

token_sequence

"

(9)

(10)

%&

(8)

Notes:
1

This is the start of the syntax diagram.

The symbol # must appear first.

The keyword pragma must follow the # symbol.

The keyword comment must follow the keyword pragma.

An opening parenthesis must follow the keyword comment.

The comment type must be entered only as one of the following: compiler,
date, timestamp, copyright, or user.

If the comment type is copyright or user, and an optional character string is


following, a comma must be present after the comment type.

A character string must follow the comma. The character string must be
enclosed in double quotation marks.

A closing parenthesis is required.

10

This is the end of the syntax diagram.

The following examples of the #pragma comment directive are syntactically correct
according to the diagram above:
Chapter 1. About This Book

11

#pragma comment(date)
#pragma comment(user)
#pragma comment(copyright,"This text will appear in the module")

12

OS/390 V2R10.0 C/C++ Language Reference

Chapter 2. About IBM OS/390 C/C++


The C/C++ feature of the IBM OS/390 licensed program provides support for C and
C++ application development on the OS/390 platform. The C/C++ feature is based
on the C/C++ for MVS/ESA product.
IBM OS/390 C/C++ includes:
v A C compiler (referred to as the OS/390 C compiler)
v A C++ compiler (referred to as the OS/390 C++ compiler)
v Support for a set of C++ class libraries that are available with the base OS/390
operating system
v Application Support Class and Collection Class Library source
v A mainframe interactive Debug Tool (optional)
v Performance Analyzer host component, which supports the C/C++ Productivity
Tools for OS/390 product
v A set of utilities for C/C++ application development
IBM offers the C language on other platforms, such as the AIX, OS/2, OS/400,
VM/ESA, VSE/ESA, and Windows operating systems. The AIX, OS/2, OS/400, and
Windows operating systems also offer the C++ language.
|

Changes for Version 2 Release 10

|
|

OS/390 C/C++ has made the following performance and usability enhancements for
this release:

|
|
|
|
|
|
|
|
|

Extra Performance Linkage (XPLINK)


Extra Performance Linkage (XPLINK) is a new call linkage between
functions that has the potential for a significant performance
increase when used in an environment of frequent calls between
small functions. XPLINK makes subroutine calls more efficient by
removing nonessential instructions from the main path. When all
functions are compiled with the XPLINK option, pointers can be
used without restriction, which makes it easier to port new
applications to S/390.

|
|
|
|
|
|

GOFF

The Generalized Object File Format (GOFF) is the strategic object


module format for S/390. It extends the capabilities of object
modules to contain more information than current object modules. It
removes the limitations of the previous object module format and
supports future enhancements. GOFF makes re-binding easier and
more efficient. It is required for XPLINK.

|
|
|
|
|

IPA Level 2

Under IPA Level 1, many optimizations such as constant


propagation and pointer analysis are performed at the
intraprocedural (subprogram) level. With IPA Level 2, these
optimizations are performed across the entire program, which can
result in significant improvement in the generated code.

|
|
|

Addition of @STATIC Map into Compiler Listing


The @STATIC Map displays offset information for file scope
read/write static variables.

This release has introduced the following compiler option:

|
|

COMPACT

Copyright IBM Corp. 1996, 2000

During optimizations performed during code generation, for both


NOIPA and IPA, choices must be made between those

13

optimizations which tend to result in faster but larger code and


those which tend to result in smaller but slower code. The COMPACT
| NOCOMPACT option controls these choices. When the COMPACT
option is used, the compiler favors those optimizations which tend
to limit the growth of the code. This feature gives you the flexibility
to choose between faster but larger code or slower and smaller
code.

|
|
|
|
|
|
|
|
|

For details on how to use this compiler option, see the chapter Compiler Options in
OS/390 C/C++ Users Guide.

|
|
|
|

The IBM System Object Model (SOM) is no longer supported in the C++ compiler
and the IBM Open Class Library. The SOM-enabled class library DLLs have been
stabilized at the V2R9 level and continue to be shipped as a run-time environment
only. You cannot use the V2R10 Compiler to build SOM applications.

The Model Tool is no longer available.

|
|
|
|
|
|
|

The option_override #pragma directive defines function-specific options that


override those specified by the command line options when performing optimization
for code and data in that subprogram. This enables finer control of program
optimization. In V2R10 we have added support for the COMPACT and SPILL options.
The subprogram-specific SPILL option is not a new option, however, the maximum
spill area size has been increased for this release to 1073741823 bytes or 2301
bytes.

OS/390 Language Environment Downward Compatibility

|
|
|
|
|
|
|

OS/390 Release 10 Language Environment provides downward compatibility


support. Assuming that you have met the required programming guidelines and
restrictions, described in OS/390 Language Environment Programming Guide, this
support enables you to develop applications on higher release levels of OS/390 for
use on platforms that are running lower release levels of OS/390. In C and C++,
downward compatibility support is provided through the C/C++ TARGET compiler
option. See the OS/390 C/C++ Users Guide for details on this compiler option.

|
|
|
|

For example, a company may use OS/390 Release 10 with Language Environment
on a development system where applications are coded, link-edited, and tested,
while using any supported lower release of OS/390 Language Environment on their
production systems where the finished application modules are used.

|
|
|
|

Downward compatibility support is not the roll-back of new function to prior releases
of OS/390. Applications developed that exploit the downward compatibility support
must not use any Language Environment function that is unavailable on the lower
release of OS/390 where the application will be used.

|
|
|
|

The downward compatibility support includes toleration PTFs for lower releases of
OS/390 to assist in diagnosing applications that do not meet the programming
requirements for this support. (Specific PTF numbers can be found in the PSP
buckets.)

|
|
|
|

The downward compatibility support provided by OS/390 Release 10 and by the


toleration PTFs does not change Language Environments upward compatibility.
That is, applications coded and link-edited with one release of OS/390 Language
Environment will continue to run on later releases of OS/390 Language

14

OS/390 V2R10.0 C/C++ Language Reference

|
|

Environment without the need to recompile or re-link edit the application,


independent of the downward compatibility support.

|
|
|
|

Downward compatibility is supported in earlier releases of OS/390 C/C++ (from


Release 6), but in earlier releases of OS/390 the user is required to copy header
files and link-edit syslib datasets from the deployment release of OS/390. With
Release 10, the Release 10 header files and syslib datasets can be used.

The C/C++ Compilers


The following sections describe the C and C++ languages and the OS/390 C/C++
compilers.

The C Language
The C language is a general purpose, versatile, and functional programming
language that allows a programmer to create applications quickly and easily. C
provides high-level control statements and data types as do other structured
programming languages. It also provides many of the benefits of a low-level
language.

The C++ Language


The C++ language is based on the C language, but incorporates support for
object-oriented concepts. Refer to the Appendix A. C and C++ Compatibility on
page 391 for a detailed description of the differences between OS/390 C++ and
OS/390 C.
The C++ language introduces classes, which are user-defined data types that may
contain data definitions and function definitions. You can use classes from
established class libraries, develop your own classes, or derive new classes from
existing classes by adding data descriptions and functions. New classes can inherit
properties from one or more classes. Not only do classes describe the data types
and functions available, but they can also hide (encapsulate) the implementation
details from user programs. An object is an instance of a class.
The C++ language also provides templates and other features that include access
control to data and functions, and better type checking and exception handling. It
also supports polymorphism and the overloading of operators.

Common Features of the OS/390 C and C++ Compilers

|
|

The C and C++ compilers offer many features to help your work:
v Optimization support:
Algorithms to take advantage of S/390 architecture to get better optimization
for speed and use of computer resources through the OPTIMIZE and IPA
compiler options.
The OPTIMIZE compiler option, which instructs the compiler to optimize the
machine instructions it generates to produce faster-running object code to
improve application performance at run time.
Interprocedural Analysis (IPA), to perform optimizations across compilation
units, thereby optimizing application performance at run time.
v DLLs (dynamic link libraries) to share parts among applications or parts of
applications, and dynamically link to exported variables and functions at run time.
DLLs allow a function reference or a variable reference in one executable to use
a definition located in another executable at run time. You can use both
Chapter 2. About IBM OS/390 C/C++

15

load-on-reference and load-on-demand DLLs. When your program refers to a


function or variable which resides in a DLL, OS/390 C/C++ generates code to
load the DLL and access the functions and variables within it. This is called
load-on-reference. Alternatively, your program can use OS/390 C library functions
to load a DLL and look up the address of functions and variables within it. This is
called load-on-demand. Your application code explicitly controls load-on-demand
DLLs at the source level.
You can use DLLs to split applications into smaller modules and improve system
memory usage. DLLs also offer more flexibility for building, packaging, and
redistributing applications.
v Full program reentrancy.
With reentrancy, many users can simultaneously run a program. A reentrant
program uses less storage if it is stored in the LPA (link pack area) or ELPA
(extended link pack area) and simultaneously run by multiple users. It also
reduces processor I/O when the program starts up, and improves program
performance by reducing the transfer of data to auxiliary storage. OS/390 C
programmers can design programs that are naturally reentrant. For those
programs that are not naturally reentrant, C programmers can use constructed
reentrancy. To do this, compile programs with the RENT option and use the
program management binder supplied with OS/390, or the OS/390 Language
Environment Prelinker (prelinker) and program management binder. The OS/390
C++ compiler always ensures that C++ programs are reentrant.
v Locale-based internationalization support derived from the IEEE POSIX
1003.2-1992 standard. Also derived from the X/Open CAE Specification, System
Interface Definitions, Issue 4 and Issue 4 Version 2. This allows programmers to
use locales to specify language/country characteristics for their applications.
v The ability to call and be called by other languages such as assembler, COBOL,
PL/1, compiled Java, and Fortran, to enable programmers to integrate OS/390
C/C++ code with existing applications.
v Exploitation of OS/390 and OS/390 UNIX technology.
OS/390 UNIX is an IBM implementation of the open operating system
environment, as defined in the XPG4 and POSIX standards.
v When used with OS/390 UNIX and OS/390 Language Environment, support for
the following standards at the system level:
A subset of the extended multibyte and wide character functions as defined by
the Programming Language C Amendment 1. This is ISO/IEC
9899:1990/Amendment 1:1994(E)
ISO/IEC 9945-1:1990(E)/IEEE POSIX 1003.1-1990
A subset of IEEE POSIX 1003.1a, Draft 6, July 1991
IEEE Portable Operating System Interface (POSIX) Part 2, P1003.2
A subset of IEEE POSIX 1003.4a, Draft 6, February 1992 (the IEEE POSIX
committee has renumbered POSIX.4a to POSIX.1c)
X/Open CAE Specification, System Interfaces and Headers, Issue 4 Version 2
A subset of IEEE 754-1985 (R1990) IEEE Standard for Binary Floating-Point
Arithmetic (ANSI), as applicable to the S/390 environment.
X/Open CAE Specification, Network Services, Issue 4
v Year 2000 support
v Support for the Euro currency.

16

OS/390 V2R10.0 C/C++ Language Reference

OS/390 C Compiler Specific Features


In addition to the features common to OS/390 C and C++, the OS/390 C compiler
provides you with the following capabilities:
v The ability to write portable code that supports the following standards:
All elements of the ISO standard ISO/IEC 9899:1990 (E)
ANSI/ISO 9899:1990[1992] (formerly ANSI X3.159-1989 C)
X/Open Specification Programming Language Issue 3, Common Usage C
FIPS-160
v System programming capabilities, which allow you to use OS/390 C in place of
assembler
v Additional optimization capabilities through the INLINE compile-time option
v Extensions of the standard definitions of the C language to provide programmers
with support for the OS/390 environment, such as fixed-point (packed) decimal
data support

OS/390 C++ Compiler Specific Features


In addition to the features common to OS/390 C and C++, the OS/390 C++
compiler provides you with the following:

v An implementation based on the definition of the language that is contained in


the Draft Proposal International Standard for Information Systems Programming
Language C++ (X3J16/92-00091). The OS/390 C++ compiler also supports a
subset of the International Standard for the C++ Programming Language
(ISO/IEC 14882-1998) specification. The following items in the standard are not
supported by OS/390 C++:
New cast syntax and semantics
- dynamic_cast
- static_cast
- reinterpret_cast

|
|

- const_cast
Explicit specifier
Mutable specifier
Namespace
Run-Time Type Identification (RTTI)

ANSI Template (supports the specification in X3J16/92-00091 as mentioned


above)
The bool built-in boolean data type
Run-time standard exceptions
- bad_alloc
- bad_exception
- bad_cast
Universal Character Names
ANSI C++ Standard Class Library (which includes the Standard Template
Library)
v C++ template support and exception handling.

Chapter 2. About IBM OS/390 C/C++

17

Utilities
The OS/390 C/C++ compilers provide the following utilities:
v The CXXFILT Utility to map OS/390 C++ mangled names to the original source.
v The localedef Utility to read the locale definition file and produce a locale object
that the locale-specific library functions can use.
v The DSECT Conversion Utility to convert descriptive assembler DSECTs into
OS/390 C/C++ data structures.
OS/390 Language Environment provides the following utilities:
v The Object Library Utility (C370LIB) to update partitioned data set (PDS and
PDS/E) libraries of object modules and Interprocedural Analysis (IPA) object
modules.
v The DLL Rename Utility to make selected DLLs a unique component of the
applications with which they are packaged. The DLL Rename Utility does not
support XPLINK.
v The prelinker which combines object modules that comprise an OS/390 C/C++
application, to produce a single object module. The prelinker supports only object
and extended object format input files, and does not support GOFF.

|
|
|
|
|
|
|
|
|

Class Libraries
IBM OS/390 C/C++ provides a base set of class libraries, called C/C++ IBM Open
Class, which is consistent with that available in other members of the VisualAge
C++ Version 3.0 product family. These class libraries are:
v The I/O Stream Class Library

The I/O Stream Class Library lets you perform input and output (I/O) operations
independent of physical I/O devices or data types that are used. You can code
sophisticated I/O statements easily and clearly, and define input and output for
your own data types. You can improve the maintainability of programs that use
input and output by using the I/O Stream Class Library.
v The Complex Mathematics Class Library
The Complex Mathematics Class Library lets you manipulate and perform
standard arithmetic on complex numbers. Scientific and technical fields use
complex numbers.
v The Application Support Class Library
The Application Support Class Library provides the basic abstractions that are
needed during the creation of most C++ applications, including String, Date,
Time, and Decimal.
v The Collection Class Library
The Collection Class Library implements a wide variety of classical data
structures such as stack, tree, list, hash table, and so on. Most programs use
collections. You can develop programs without having to define every collection.
Programmers can start programming by using a high level of abstraction, and
later replace an abstract data type with the appropriate concrete implementation.
Each abstract data type has a common interface for all of its implementations.
The Collection Class Library provides programmers with a consistent set of
building blocks from which they can derive application objects. The library design
exploits features of the C++ language such as exception handling and template
support.
All of the libraries that are described above are thread-safe.

18

OS/390 V2R10.0 C/C++ Language Reference

All of the libraries that are described above are available in both static and DLL
formats. OS/390 C/C++ packages the Application Support Class and Collection
Class libraries together in a single DLL. For compatibility, separate side-decks are
available for the Application Support Class and Collection Class libraries, in addition
to the side-deck available for the combined library.
Note: Retroactive to OS/390 Version 1 Release 3, the IBM Open Class Library is
licensed with the base operating system. This enables applications to use
this library at run time without having to license the OS/390 C/C++ compiler
feature(s) or to use the DLL Rename Utility.
|
|
|
|
|
|
|
|
|
|
|
|
|

The DLLs for the Open Class libraries are compiled without XPLINK. If you use
these DLLs with XPLINK applications, the performance gain you realize in your
application code by using XPLINK may be offset partially or completely (depending
on the frequency of use of DLL functions) by the cost of switching to the non-XPLINK
environment when crossing the boundary between your application code and the
class library code in the DLL. If you use these DLLs with XPLINK applications, you
may notice reduced performance. There are two ways to avoid this problem:
v Use the static library instead of the DLL. This static library has both the XPLINK
and NOXPLINK versions of the objects.
v For the Application Support Class Library or Collection Class Library, recompile
the source code that is shipped with OS/390 C/C++. For build instructions, refer
to the CBC.SCLDBLD readme file.

Class Library Source


The Class Library Source consists of the following:
v Application Support Class Library source code

v Collection Class Library source code (C++ native)


v Instructions for building the Application Support Class and Collection Class
Libraries in C++ native (static and DLL) versions
v Class Library Language Environment message file source
v Instructions for building the Class Library Language Environment message files

The Debug Tool


IBM OS/390 C/C++ supports program development by using theDebug Tool. This
optionally available tool allows you to debug applications in their native host
environment, such as CICS/ESA, IMS/ESA, DB2, and so on. The Debug Tool
provides the following support and function:
v Step mode
v Breakpoints
v Monitor
v Frequency analysis
v Dynamic patching
You can record the debug session in a log file, and replay the session. You can also
use the Debug Tool to help capture test cases for future program validation or to
further isolate a problem within an application.

You can specify either data sets or hierarchical file system (HFS) files as source
files.

|
|

Note: You can also use the dbx shell command to debug programs, as described in
OS/390 UNIX System Services Command Reference, SC28-1892.
Chapter 2. About IBM OS/390 C/C++

19

For further information, see IBM C/C++ Productivity Tools for OS/390.

IBM C/C++ Productivity Tools for OS/390


With the IBM C/C++ Productivity Tools for OS/390 product, you can expand your
OS/390 application development environment out to the workstation, while
remaining close to your familiar host environment. IBM C/C++ Productivity Tools for
OS/390 includes the following workstation-based tools to increase your productivity
and code quality:
v A Performance Analyzer to help you analyze, understand, and tune your C and
C++ applications for improved performance
v A Distributed Debugger that allows you to debug C or C++ programs from the
convenience of the workstation
v A workstation-based editor to improve the productivity of your C and C++ source
entry
v Advanced online help, with full text search and hypertext topics as well as
printable, viewable, and searchable Portable Document Format (PDF) documents
In addition, IBM C/C++ Productivity Tools for OS/390 includes the following host
components:
v Debug Tool
v Host Performance Analyzer
Use the Performance Analyzer on your workstation to graphically display and
analyze a profile of the execution of your host OS/390 C or C++ application. Use
this information to time and tune your code so that you can increase the
performance of your application.
Use the Distributed Debugger to debug your OS/390 C/C++ application remotely
from your workstation. Set a break point with the simple click of the mouse. Use the
windowing capabilities of your workstation to view multiple segments of your source
and your storage, while monitoring a variable at the same time.
Use the workstation-based editor to quickly develop C and C++ application code
that runs on OS/390. Context-sensitive help information is available to you when
you need it.
References to Performance Analyzer in this document refer to the IBM OS/390
Performance Analyzer included in the C/C++ Productivity Tools for OS/390 product.

OS/390 Language Environment


IBM OS/390 C/C++ exploits the C/C++ runtime environment and library of runtime
services available with OS/390 Language Environment (formerly Language
Environment for MVS & VM, Language Environment/370 and LE/370).
OS/390 Language Environment consists of four language-specific runtime libraries,
and Base Routines and Common Services, as shown below. OS/390 Language
Environment establishes a common runtime environment and common runtime
services for language products, user programs, and other products.

20

OS/390 V2R10.0 C/C++ Language Reference

C/C++
Language
Specific
Library

COBOL
Language
Specific
Library

PL/I
Language
Specific
Library

FORTRAN
Language
Specific
Library

Language Environment Base Routines and Common Services


Figure 1. Libraries in OS/390 Language Environment

The common execution environment is composed of data items and services that
are included in library routines available to an application that runs in the
environment. The OS/390 Language Environment provides a variety of services:
v Services that satisfy basic requirements common to most applications. These
include support for the initialization and termination of applications, allocation of
storage, interlanguage communication (ILC), and condition handling.
v Extended services that are often needed by applications. OS/390 C/C++ contains
these functions within a library of callable routines, and include interfaces to
operating system functions and a variety of other commonly used functions.
v Runtime options that help in the execution, performance, and diagnosis of your
application.
v Access to operating system services; OS/390 UNIX services are available to an
application programmer or program through the OS/390 C/C++ language
bindings.
v Access to language-specific library routines, such as the OS/390 C/C++ library
functions.
For more information, see the Language Environment home page at the following
web address:
http://www.ibm.com/s390/le/

The Program Management Binder


The binder provided with OS/390 combines the object modules, load modules, and
program objects comprising an OS/390 application. It produces a single output
program object or load module that you can load for execution. The binder supports
all C and C++ code, provided that you store the output program in a PDSE
(Partitioned Data Set Extended) member or an HFS file.
If you cannot use a PDSE member or HFS file, and your program contains C++
code, or C code that is compiled with any of the RENT, LONGNAME, DLL or IPA
compile-time options, you must use the prelinker.
Using the binder without using the prelinker has the following advantages:
v Faster rebinds when recompiling and rebinding a few of your source files
v Rebinding at the single compile unit level of granularity (except when you use the
IPA compile-time option)
Chapter 2. About IBM OS/390 C/C++

21

v Input of object modules, load modules, and program objects


v Improved long name support:
Long names do not get converted into prelinker generated names
Long names appear in the binder maps, enabling full cross-referencing
Variables do not disappear after prelink
Fewer steps in the process of producing your executable program

The prelinker provided with OS/390 Language Environment combines the object
modules comprising an OS/390 C/C++ application and produces a single object
module. You can link-edit the object module into a load module (which is stored in a
PDS), or bind it into a load module or a program object stored in a PDS, PDSE, or
HFS file.

|
|

Note: For further information on the binder, refer to the DFSMS home page at
http://www.ibm.com/storage/software/sms/smshome.htm.

OS/390 UNIX System Services (OS/390 UNIX)


OS/390 UNIX provides capabilities under OS/390 to make it easier to implement or
port applications in an open, distributed environment. OS/390 UNIX Services are
available to OS/390 C/C++ application programs through the C/C++ language
bindings available with OS/390 Language Environment.
Together, the OS/390 UNIX Services, OS/390 Language Environment, and OS/390
C/C++ compilers provide an application programming interface that supports
industry standards.
OS/390 UNIX provides support for both existing OS/390 applications and new
OS/390 UNIX applications:
v C programming language support as defined by ISO/ANSI C
v C++ programming language support
v C language bindings as defined in the IEEE 1003.1 and 1003.2 standards;
subsets of the draft 1003.1a and 1003.4a standards; X/Open CAE Specification:
System Interfaces and Headers, Issue 4, Version 2, which provides standard
interfaces for better source code portability with other conforming systems; and
X/Open CAE Specification, Network Services, Issue 4, which defines the X/Open
UNIX descriptions of sockets and X/Open Transport Interface (XTI)
v OS/390 UNIX Extensions that provide OS/390-specific support beyond the
defined standards
v The OS/390 UNIX Shell and Utilities feature, which provides:
A shell, based on the Korn Shell and compatible with the Bourne Shell
A shell, tcsh, based on the C shell, csh
Tools and utilities that support the X/Open Single UNIX Specification, also
known as X/Open Portability Guide (XPG) Version 4, Issue 2, and provide
OS/390 support. The following is a partial list of utilities that are included:

22

ar

Creates and maintains library archives

BPXBATCH

Allows you to submit batch jobs that run shell commands,


scripts, or OS/390 C/C++ executable files in HFS files from a
shell session

c89

Compiles, assembles, and binds OS/390 UNIX C applications

dbx

Provides an environment to debug and run programs

OS/390 V2R10.0 C/C++ Language Reference

gencat

Merges the message text source files Messagefile (usually


*.msg) into a formatted message Catalogfile (usually *.cat)

iconv

Converts characters from one code set to another

lex

Automatically writes large parts of a lexical analyzer based on


a description that is supplied by the programmer

localedef

Creates a compiled locale object

make

Helps you manage projects containing a set of interdependent


files, such as a program with many OS/390 C/C++ source and
object files, keeping all such files up to date with one another

yacc

Allows you to write compilers and other programs that parse


input according to strict grammar rules
Support for other utilities such as:
c++

Compiles, assembles, and binds OS/390 UNIX C++


applications

mkcatdefs

Preprocesses a message source file for input to the gencat


utility

runcat

Invokes mkcatdefs and pipes the message catalog source


data (the output from mkcatdefs) to gencat

dspcat

Displays all or part of a message catalog

dspmsg
Displays a selected message from a message catalog
v The OS/390 UNIX Debugger feature, which provides the dbx interactive symbolic
debugger for OS/390 UNIX applications
v OS/390 UNIX, which provides access to a hierarchical file system (HFS), with
support for the POSIX.1 and XPG4 standards
v OS/390 C/C++ I/O routines, which support using HFS files, standard OS/390
data sets, or a mixture of both
v Application threads (with support for a subset of POSIX.4a)
v Support for OS/390 C/C++ DLLs
OS/390 UNIX offers program portability across multivendor operating systems, with
support for POSIX.1, POSIX.1a (draft 6), POSIX.2, POSIX.4a (draft 6), and
XPG4.2.
To application developers who have worked with other UNIX environments, the
OS/390 UNIX Shell and Utilities are a familiar environment for C/C++ application
development. If you are familiar with existing MVS development environments, you
may find that the OS/390 UNIX environment can enhance your productivity. Refer to
OS/390 UNIX System Services Users Guide for more information on the Shell and
Utilities.
For more information, see the OS/390 UNIX home page at the following web
address:
http://www.ibm.com/s390/unix/

Chapter 2. About IBM OS/390 C/C++

23

OS/390 C/C++ Applications with OS/390 UNIX C/C++ Functions


All OS/390 UNIX C functions are available at all times. In some situations, you must
specify the POSIX(ON) runtime option. This is required for the POSIX.4a threading
functions, and the system() and signal handling functions where the behavior is
different between POSIX/XPG4 and ANSI. Refer to OS/390 C/C++ Run-Time
Library Reference for more information about requirements for each function.
You can invoke an OS/390 C/C++ program that uses OS/390 UNIX C functions
using the following methods:
v Directly from an OS/390 UNIX Shell.
v From another program, or from an OS/390 UNIX Shell, using one of the exec
family of functions, or the BPXBATCH utility from TSO or MVS batch.
v Using the POSIX system() call.
v Directly through TSO or MVS batch without the use of the intermediate
BPXBATCH utility. In some cases, you may require the POSIX(ON) runtime option.

Input and Output


The C/C++ runtime library that supports the OS/390 C/C++ compiler supports
different input and output (I/O) interfaces, file types, and access methods. The C++
I/O Stream Class Library provides additional support.

I/O Interfaces
The C/C++ runtime library supports the following I/O interfaces:
C Stream I/O
This is the default and the ANSI-defined I/O method. This method
processes all input and output by character.
Record I/O
The library can also process your input and output by record. A record is a
set of data that is treated as a unit. It can also process VSAM data sets by
record. Record I/O is an OS/390 C/C++ extension to the ANSI standard.
TCP/IP Sockets I/O
OS/390 UNIX provides support for an enhanced version of an
industry-accepted protocol for client/server communication that is known as
sockets. A set of C language functions provides support for OS/390 UNIX
sockets. OS/390 UNIX sockets correspond closely to the sockets that are
used by UNIX applications that use the Berkeley Software Distribution
(BSD) 4.3 standard (also known as OE sockets). The slightly different
interface of the X/Open CAE Specification, Networking Services, Issue 4, is
supplied as an additional choice. This interface is known as X/Open
Sockets.
The OS/390 UNIX socket application program interface (API) provides
support for both UNIX domain sockets and Internet domain sockets. UNIX
domain sockets, or local sockets, allow interprocess communication within
OS/390 independent of TCP/IP. Local sockets behave like traditional UNIX
sockets and allow processes to communicate with one another on a single
system. With Internet sockets, application programs can communicate with
others in the network using TCP/IP.

24

OS/390 V2R10.0 C/C++ Language Reference

In addition, the C++ I/O Stream Library supports formatted I/O in C++. You can
code sophisticated I/O statements easily and clearly, and define input and output for
your own data types. This helps improve the maintainability of programs that use
input and output.

File Types
In addition to conventional files, such as sequential files and partitioned data sets,
the C/C++ runtime library supports the following file types:
Virtual Storage Access Method (VSAM) Data Sets
OS/390 C/C++ has native support for three types of VSAM data
organization:
v Key-sequenced data sets (KSDS). Use KSDS to access a record through
a key within the record. A key is one or more consecutive characters that
are taken from a data record that identifies the record.
v Entry-sequenced data sets (ESDS). Use ESDS to access data in the
order it was created (or in the reverse order).
v Relative-record data sets (RRDS). Use RRDS for data in which each
item has a particular number (for example, a telephone system with a
record associated with each number).
For more information on how to perform I/O operations on these VSAM file
types, see OS/390 C/C++ Programming Guide.
Hierarchical File System Files
OS/390 C/C++ recognizes Hierarchical File System (HFS) file names. The
name specified on the fopen() or freopen() call has to conform to certain
rules (described in OS/390 C/C++ Programming Guide). You can create
regular HFS files, special character HFS files, or FIFO HFS files. You can
also create links or directories.
Memory Files
Memory files are temporary files that reside in memory. For improved
performance, you can direct input and output to memory files rather than to
devices. Since memory files reside in main storage and only exist while the
program is executing, you primarily use them as work files. You can access
memory files across load modules through calls to non-POSIX system()
and C fetch(); they exist for the life of the root program. Standard streams
can be redirected to memory files on a non-POSIX system() call using
command line redirection.
Hiperspace Expanded Storage
Large memory files can be placed in Hiperspace expanded storage to free
up some of your home address space for other uses. Hiperspace expanded
storage or high performance space is a range of up to 2 gigabytes of
contiguous virtual storage space. A program can use this storage as a
buffer (1 gigabyte = 230 bytes).

Additional I/O Features


IBM OS/390 C/C++ provides additional I/O support through the following features:
v User error handling for serious I/O failures (SIGIOERR)
v Improved sequential data access performance through enablement of the
DFSMS/MVS support for 31-bit sequential data buffers and sequential data
striping on extended format data sets
v Full support of PDS/Es on OS/390 including support for multiple members
opened for write
Chapter 2. About IBM OS/390 C/C++

25

v
v
v
v

Overlapped I/O support under OS/390 (NCP, BUFNO)


Multibyte character I/O functions
Fixed-point (packed) decimal data type support in formatted I/O functions
Support for multiple volume data sets that span more than one volume of DASD
or tape
v Support for Generation Data Group I/O

The System Programming C Facility


The System Programming C (SPC) facility allows you to build applications that
require no dynamic loading of OS/390 Language Environment libraries. It also
allows you to tailor your application to better utilize the low-level services available
on your operating system. SPC offers a number of advantages:
v You can develop applications that you can execute in a customized environment
rather than with OS/390 Language Environment services. Note that if you do not
use OS/390 Language Environment services, only some built-in functions and a
limited set of C/C++ runtime library functions are available to you.
v You can substitute the OS/390 C language in place of assembler language when
writing system exit routines, by using the interfaces that are provided by SPC.
v SPC lets you develop applications featuring a user-controlled environment, in
which an OS/390 C environment is created once and used repeatedly for C
function execution from other languages.
v You can utilize co-routines, by using a two-stack model to write application
service routines. In this model, the application calls on the service routine to
perform services independently of the user. The application is then suspended
when control is returned to the user application.

Interaction with Other IBM Products


When you use OS/390 C/C++, you can write programs that utilize the power of
other IBM products and subsystems:
v Cross System Product (CSP)
Cross System Product/Application Development (CSP/AD) is an application
generator that provides ways to interactively define, test, and generate
application programs to improve productivity in application development. Cross
System Product/Application Execution (CSP/AE) takes the generated program
and executes it in a production environment.
Note: You cannot compile CSP applications with the OS/390 C++ compiler.
However, your OS/390 C++ program can use interlanguage calls (ILC) to
call OS/390 C programs that access CSP.
v Customer Information Control System (CICS)
You can use the CICS/ESA Command-Level Interface to write C/C++ application
programs. The CICS Command-Level Interface provides data, job, and task
management facilities that are normally provided by the operating system.
Note: Code preprocessed with CICS/ESA versions prior to V4 R1 is not
supported for OS/390 C++ applications. OS/390 C++ code preprocessed
on CICS/ESA V4 R1 cannot run under CICS/ESA V3 R3.
v DB2 Universal Database (UDB) for OS/390

26

OS/390 V2R10.0 C/C++ Language Reference

DB2 programs manage data that is stored in relational databases. You can
access the data by using a structured set of queries that are written in Structured
Query Language (SQL).
The DB2 program uses SQL statements that are embedded in the program. The
SQL translator (DB2 preprocessor) translates the embedded SQL into host
language statements that perform the requested functions. The OS/390 C/C++
compilers compile the output of the SQL translator. The DB2 program processes
a request, and processing returns to the application.
v Data Window Services (DWS)
The Data Window Services (DWS) part of the Callable Services Library allows
your OS/390 C or OS/390 C++ program to manipulate temporary data objects
that are known as TEMPSPACE and VSAM linear data sets.
v Information Management System (IMS)
The Information Management System/Enterprise Systems Architecture (IMS/ESA)
product provides support for hierarchical databases.
v Interactive System Productivity Facility (ISPF)
OS/390 C/C++ provides access to the Interactive System Productivity Facility
(ISPF) Dialog Management Services. A dialog is the interaction between a
person and a computer. The dialog interface contains display, variable, message,
and dialog services as well as other facilities that are used to write interactive
applications.
v Graphical Data Display Manager (GDDM)
GDDM provides a comprehensive set of functions to display and print
applications most effectively:
A windowing system that the user can tailor to display selected information
Support for presentation and keyboard interaction
Comprehensive graphics support
Fonts including support for double-byte character set (DBCS)
Business image support
Saving and restoring graphic pictures
Support for many types of display terminals, printers, and plotters
v Query Management Facility (QMF)
OS/390 C supports the Query Management Facility (QMF), a query and report
writing facility, which allows you to write applications through a callable interface.
You can create applications to perform a variety of tasks, such as data entry,
query building, administration aids, and report analysis.
v OS/390 Java Support
The Java language supports the Java Native Interface (JNI) for making calls to
and from C/C++. These calls do not use ILC support but rather the Java defined
interface JNI. Java code, which has been compiled using the High Performance
Compiler for Java (HPCJ), will support the JNI interface. There is no distinction
between compiled Java and interpretted Java as far as calls to C or C++.

Additional Features of OS/390 C/C++


Feature

| long long Data Type


|
Multibyte Character Support

Description
The OS/390 C/C++ compiler supports long long as a native data type in
LANGLVL(EXTENDED) mode.
OS/390 C/C++ supports multibyte characters for those national languages such as
Japanese whose characters cannot be represented by a single byte.
Chapter 2. About IBM OS/390 C/C++

27

Feature

Description

Wide Character Support

Multibyte characters can be normalized by OS/390 C library functions and encoded in


units of one length. These normalized characters are called wide characters.
Conversions between multibyte and wide characters can be performed by string
conversion functions such as wcstombs(), mbstowcs(), wcsrtombs(), and mbsrtowcs(),
as well as the family of wide-character I/O functions. Wide-character data can be
represented by the wchar_t data type.

Extended Precision
Floating-Point Numbers

OS/390 C/C++ provides three S/390 floating-point number data types: single precision
(32 bits), declared as float; double precision (64 bits), declared as double; and
extended precision (128 bits), declared as long double.
Extended precision floating-point numbers give greater accuracy to mathematical
calculations.
As of Release 6, OS/390 C/C++ also supports IEEE 754 floating-point representation.
By default, float, double, and long double values are represented in IBM S/390
floating point format. However, the IEEE 754 floating-point representation is used if you
specify the FLOAT(IEEE754) compile option. For details on this support, see the
description of the FLOAT option in OS/390 C/C++ Users Guide.

|
|
|
|
|

Command Line Redirection

You can redirect the standard streams stdin, stderr, and stdout from the command
line or when calling programs using the system() function.

National Language Support

OS/390 C/C++ provides message text in either American English or Japanese. You can
dynamically switch between the two languages.

Locale Definition Support

OS/390 C/C++ provides a locale definition utility that supports the creation of separate
files of internationalization data, or locales. Locales can be used at run time to
customize the behavior of an application to national language, culture, and coded
character set (code page) requirements. Locale-sensitive library functions, such as
isdigit(), use this information.

Coded Character Set (Code


page) Support

The OS/390 C/C++ compiler can compile C/C++ source written in different EBCDIC
code pages. In addition, the iconv utility converts data or source from one code page to
another.

Selected Built-in Library


Functions

Selected library functions, such as string and character functions, are built into the
compiler to improve performance execution. Built-in functions are compiled into the
executable, and no calls to the library are generated.

Multi-threading

Threads are efficient in applications that allow them to take advantage of any
underlying parallelism available in the host environment. This underlying parallelism in
the host can be exploited either by forking a process and creating a new address
space, or by using multiple threads within a single process. For more information, refer
to the OS/390 C/C++ Programming Guide

Multitasking Facility (MTF)

Multitasking is a mode of operation where your program performs two or more tasks at
the same time. OS/390 C provides a set of library functions that perform multitasking.
These functions are known as the Multitasking Facility (MTF). MTF uses the
multitasking capabilities of OS/390 to allow a single OS/390 C application program to
use more than one processor of a multiprocessing system simultaneously.
Note: XPLINK is not supported in an MTF environment. You can also use threads to
perform multitasking with or without XPLINK, as described in the OS/390 C/C++
Programming Guide.

Packed Structures and

OS/390 C provides support for packed structures and unions. Structures and unions
may be packed to reduce the storage requirements of an OS/390 C program or to
define structures that are laid out according to COBOL or PL/I structure layout rules.

|
|
|
|
| Unions
|
Fixed-point (Packed)
Decimal Data

OS/390 C supports fixed-point (packed) decimal as a native data type for use in
business applications. The packed data type is similar to the COBOL data type COMP-3
or the PL/I data type FIXED DEC, with up to 31 digits of precision.
The Application Support Class Library provides the Binary Coded Decimal Class for
C++ programs.

28

OS/390 V2R10.0 C/C++ Language Reference

|
|
|
|
|

Feature

Description

Long Name Support

For portability, external names can be mixed case and up to 1024 characters in length.
For C++, the limit applies to the mangled version of the name.

System Calls

You can call commands or executable modules using the system() function under
OS/390, OS/390 UNIX, and TSO. You can also use the system() function to call
EXECs on OS/390 and TSO, or Shell scripts using OS/390 UNIX.

Exploitation of ESA

Support for OS/390, IMS/ESA, Hiperspace expanded storage, and CICS/ESA allows
you to exploit the features of the ESA.

Exploitation of hardware

Use the ARCHITECTURE compiler option to select the minimum level of machine
architecture on which your program will run. ARCH(2) instructs the compiler to generate
faster instruction sequences available only on newer machines. ARCH(3) also generates
these faster instruction sequences and enables support for IEEE 754 Binary
Floating-Point instructions. Code compiled with ARCH(2) runs on a G2, G3, G4, and
2003 processor and code compiled with ARCH(3) runs on a G5 or G6 processor, and
follow-on models.
Use the TUNE compiler option to optimize your application for a selected machine
architecture. TUNE impacts performance only; it does not impact the processor model on
which you will be able to run your application. TUNE(3) optimizes your application for the
newer G4, G5, and G6 processors. TUNE(2) optimizes your application for other
architectures. For information on which machines and architectures support the above
options, refer to the ARCHITECTURE and TUNE compiler information in OS/390 C/C++
Users Guide.

Chapter 2. About IBM OS/390 C/C++

29

30

OS/390 V2R10.0 C/C++ Language Reference

Part 2. The C and C++ Languages


This part of the Language Reference describes the language elements that are
common to C and C++. It also describes the C++ constructs that support
object-oriented programming.
Chapter 3. Introduction to C and C++
Provides a brief overview of the features of C and C++, including a
description of the C++ constructs that support object-oriented programming.
Chapter 4. Lexical Elements of C and C++
Describes the basic elements of C and C++.
Chapter 5. Declarations
Describes the declarations and declarators. It also describes program
linkage, storage classes, fundamental data types, and initialization of the
fundamental data types.
Chapter 6. Expressions and Operators
Describes the expressions and standard C and C++ operators used in
computation.
Chapter 7. Implicit Type Conversions
Describes the standard conversions performed on the fundamental data
types.
Chapter 8. Functions
Describes the form and use of functions, including function declarations and
definitions.
Chapter 9. Statements
Describes the statements used to control the execution sequence of
programs.
Chapter 10. Preprocessor Directives
Discusses preprocessor directives and OS/390 C/C++ pragmas.

Copyright IBM Corp. 1996, 2000

31

32

OS/390 V2R10.0 C/C++ Language Reference

Chapter 3. Introduction to C and C++


This chapter describes the C and C++ programming languages that are
implemented by OS/390 C/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. Specifically, it discusses
the following topics:
v Overview of the C Language
v C Source Programs on page 34
v C Source Files on page 35
v Program Execution on page 36
v Scope in C on page 37
v
v
v
v
v
v

Program Linkage on page 38


Storage Duration on page 40
Name Spaces on page 40
Command-Line Arguments on page 41
Command-Line Arguments on page 41
Overview of the C++ Language on page 43

v C++ Support for Object-Oriented Programming on page 43


v C++ Programs on page 45
v Scope in C++ on page 47
v Simple C++ Input and Output on page 48
v Linkage Specifications Linking to non-C++ Programs on page 50

Overview of the C Language


C is a programming language that is designed for a wide variety of programming
tasks. You can use it for system-level code, text processing, graphics, and 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). It is also consistent and with the International Standard C (ANSI/ISO-IEC
9899-1990[1992]). This standard has officially replaced American National Standard
for Information SystemsProgramming Language C (X3.159-1989) and is
technically equivalent to the ANSI** C standard.
C supports several data types, including character, packed decimal, integer,
floating-point, and pointer 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 that is
added through its library. This division enables C to be both flexible and efficient. An
additional benefit is that the language is 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.

Copyright IBM Corp. 1996, 2000

33

Overview of the C Language


The OS/390 C/C++ Run-Time Library Reference describes all of the C library
functions.

C Source Programs
A C source program is a collection of one or more directives, declarations, and
statements that is contained in one or more source files. The contents of the
collection of files processed by a single compilation constitutes a compilation unit.
Refer to Glossary on page 415 for a more detailed definition of a compilation unit.
Statements

Specify the action the program performs.

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 that a program calls when you run the program.
Note: This is not the case for C++ programs. If a C++ program instantiates an
object in file scope, OS/390 C/C++ executes the constructor for that object
first.
By convention, main() is the starting point for running a program. It typically calls
other functions. A program usually stops running at:
v The end of the main() function
v A return statement in the main() function
v An exit function call.

CBC3RAAA - example 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;

34

OS/390 V2R10.0 C/C++ Language Reference

C Source Programs
int main(void)
{

/* Function definition
for main function

*/

double z;
double w;

/* Local variable definitions

*/

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);
printf ("cosine of y is %f\n", w);
}

/* Print cosine of x
/* 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.

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 or program object, you compile the separate source files individually and
then link or bind them as one program. With the #include directive, you can
combine source files into larger source files. The resulting collection of files that are
seen by the compiler in a single compilation is known as a compilation unit. A
compilation unit does not necessarily constitute the entire program.
A source file contains any combination of directives, declarations, statements, 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 you
compile the source file, the preprocessor alters the source file in a predictable way.
The preprocessor directives determine what changes the preprocessor makes to
the source text. As a result of the preprocessing stage, OS/390 C/C++ completes
the preprocessor directives and expands macros. It may create a new source file
that contains C statements, processed 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.
The following example is a C program in two source files. The main() and max()
functions are in separate files. The program starts by running the main() function.

CBC3RAAB - Source File 1


/************************************************************************
* Source file 1 - main function
*
************************************************************************/
#define ONE
#define TWO
#define THREE

1
2
3

extern int max(int, int);

/* Function declaration */
Chapter 3. Introduction to C and C++

35

C Source Files
int main(int argc, char * argv[])
{
int u, w, x, y, z;

/* Function definition

*/

u = 5;
z = 2;
w = max(u, ONE);
x = max(w,TWO);
y = max(x,THREE);
z = max(y,z);
return z;

CBC3RMAX - 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. They 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 the function
main() calls four times. After you compile the source files, you can bind and run
them as a single program.

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. OS/390 C/C++
executes the statements within the main() function 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 modular by creating separate functions to perform a
specific task or set of tasks. The main() function calls these functions to perform
the tasks. When your program makes a function call, it executes statements
sequentially. It starts with the first statement in the function until it encounters a
statement that alters the flow of control. 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 you call functions, they
receive values for their parameters from the arguments that you pass in 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

36

OS/390 V2R10.0 C/C++ Language Reference

Program Execution
the program can pass such values as described in The main() Function on
page 183 .

Scope in C
An identifier becomes visible with its declaration. The region where an identifier is
visible is the identifiers scope. The four kinds of scope are:
v Block
v Function
v File
v Function prototype.
The location of the identifier determines where the identifier is declared. See
Identifiers on page 58 for more information on identifiers.

Block Scope
The identifiers declaration is located inside a statement block. A block starts with an
opening brace ({) and ends with a matching closing brace (}). An identifier with
block scope is visible from the point where you declare it to the closing brace that
ends the block. You can also refer to block scope as local scope.
You can nest block visibility. A block that is nested inside a block can contain
declarations that reuses names declared in the outer block. The new declaration
applies to the inner block. OS/390 C/C++ restores the original declaration when
program control returns to the outer block. A name from the outer block is visible
inside inner blocks that do not redefine the name.

Function Scope
The only type of identifier with function scope is a label name. You implicitly declare
a label by its appearance in the program text. A label is visible throughout the
function that declares it. A goto statement transfers control to the label that is
specified on the goto statement. The label is visible to any goto statement that
appears in the same function as the label.

File Scope
The identifiers declaration appears outside of any block or parameter list. It is
visible from the point in the program where you declare it 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. The identifier will be visible to all included files
that appear after the declaration of the identifier. You can declare the identifier again
as a block-scope variable. The new declaration replaces the file-scope declaration
until the end of the block.

Function Prototype Scope


The identifiers declaration appears within the list of parameters in a function
prototype. It is visible from the point where you declare it to the closing parenthesis
of the prototype declaration.

Example of Scope in C
The following example declares the variable x on line 1, which is different from the
x it declares on line 2. The declared variable on line 2 has function prototype scope

Chapter 3. Introduction to C and C++

37

Scope in C
and is visible only up to the closing parenthesis of the prototype declaration. The
variable x declared on line 1 resumes visibility after the end of the prototype
declaration.
1
2
3
4
5
6
7

int x = 4;
/* variable x defined with file scope */
long myfunc(int x, long y); /* variable x has function
*/
/* prototype scope
*/
int main(void)
{
/* . . . */
}

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);
{

int i = 2, j = 3;
printf("%d\n%d\n", i, j);
{

/* Prints 1 */
/* i and j defined at
block scope */
/* 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;
}

Related Information
v
v
v
v
v
v
v

C Source Files on page 35


static Storage Class Specifier on page 83
Chapter 8. Functions on page 173
Labels on page 195
Block on page 196
goto on page 206
Scope in C++ on page 47

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 you declare
it.
A file scope identifier has one of the following kinds of linkage:

38

OS/390 V2R10.0 C/C++ Language Reference

Program 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 you
can refer to as linkage. While it relates to program linkage, a calling
convention concerns itself with C++ linkage specifications and the use of
certain keywords. This section only discusses program linkage.
Use linkage specifications to link to non-C++ declarations. In C, the #pragma
linkage directive specifies non-C declarations.
See Linkage Specifications Linking to non-C++ Programs on page 50 for more
information.

Internal Linkage
The following kinds of identifiers have internal linkage:
v 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.
v C++ inline functions.
v C++ identifiers declared at file scope with the specifier const and not explicitly
declared extern. In C, const objects have external linkage by default.
You can define a variable that has static storage class 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 you can see its declaration. If the definition
occurs outside a function, the variable has internal linkage. It is available from the
point where it is defined to the end of the current source file.
A class is local to its compilation unit if it has no static members or no inline
member functions, and if it has not been used in the declaration of an object,
function, or class.
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.

External Linkage
The following kinds of identifiers have external linkage:
v Identifiers with file or block scope that have the keyword extern in their
declarations, and the previously visible declaration is not static.
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.
v Function identifiers declared without storage-class specifiers.
v Object identifiers that have file scope declarations without a storage-class
specified. OS/390 C/C++ allocates storage for such object identifiers.
v Static class members and no inline member functions.

Chapter 3. Introduction to C and C++

39

Program Linkage
You can define identifiers that are declared with the keyword extern in other
compilation units.

No Linkage
The following kinds of identifiers have no linkage:
v Identifiers that do not represent an object or a function, including labels,
enumerators, typedef names, type names, and template names
v Identifiers that represent a function argument
v Identifiers declared inside a block without the keyword extern

Storage Duration
Storage duration determines how long storage for an object exists. An object has
either static storage duration or automatic storage duration, but this depends on its
declaration.
Static storage

OS/390 allocates this storage at initialization and it


remains available until the program ends. Objects
have static storage duration if they:
v Have file scope OR
v Have external or internal linkage OR
v Contain the static storage class specifier.

Automatic storage

OS/390 C/C++ allocates and removes this storage


according to the scope of the identifier. Objects
have automatic storage duration if they are any of
the following:
v Parameters in a function definition
v Declared at block scope and do not have any
storage class specifier
v Declared at block scope, and contain 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. OS/390 C/C++ creates heap
objects at run time and allocates storage for them by calling a function such
as malloc().

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. You can
use the same identifier 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.
You can redefine identifiers in the same name space but within enclosed program
blocks as described in Scope in C on page 37.

40

OS/390 V2R10.0 C/C++ Language Reference

Name Spaces
Within each of the following four name spaces, the identifiers must be unique.
v Tags of these types must be unique within a single scope:
Enumerations
Structures and unions
v Members of structures, unions, and classes must be unique within a single
structure, union, or class type.
v Statement labels have function scope and must be unique within a function.
v 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:;
return 0;

/*

*/
*/
*/

null statement label */

OS/390 C/C++ interprets each occurrence of student 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, OS/390 C/C++ passes control to the null statement label. In other
contexts, the identifier student refers to the structure variable.

Related Information
v
v
v
v

Scope in C on page 37
Identifiers on page 58
Type Specifiers on page 87
Chapter 6. Expressions and Operators on page 133

Command-Line Arguments
The maximum allowable length of a command-line argument for OS/390 Language
Environment is 64K.
OS/390 C/C++ treats arguments that you enter on the command line differently in
different environments. The following lists how argv and argc are handled.

Under OS/390 Batch


argc

Returns the number of strings in the argument line

argv[0]

Returns the program name in uppercase


Chapter 3. Introduction to C and C++

41

Command-Line Arguments
argv[1 to n]

Returns the arguments as you enter them

argc

Returns 1

argv[0]

Is a null pointer

argc

Returns 1

argv[0]

Returns the transaction ID

Under IMS

Under CICS

Under TSO Command


argc

Returns the number of strings in the argument line

argv[0]

Returns the program name in uppercase

argv[1 to n]

Returns the arguments exactly as you enter them

Under TSO Call


Without the ASIS option:
argc

Returns the number of strings in the argument line

argv

Returns the program name and arguments in


lowercase

With the ASIS option:


argc

Returns the number of strings in the argument line

argv[0]

Returns the program name in uppercase

argv[1 to n]

Arguments entered in uppercase are returned in


lowercase. Arguments entered in mixed or
lowercase are returned as entered.

Under OS/390 UNIX Shell


argc

Returns the number of strings in the argument line

argv[0]

Returns the program name as you enter it

argv[1 to n]

Returns the arguments exactly as you enter them

The only delimiter for the arguments that are passed to main() is white space.
OS/390 C/C++ uses commas passed to main() by JCL as arguments and not as
delimiters.
The following example appends the comma to the 'one' when passed to main().
//FUNC EXEC PCGO,GPGM='FUNC',
//
PARM.GO=('one',
//
'two')

For more information on restrictions of the command-line arguments, refer to the


OS/390 C/C++ Users Guide.

42

OS/390 V2R10.0 C/C++ Language Reference

Command-Line Arguments

Related Information
v
v
v
v
v

Calling Functions and Passing Arguments on page 184


Parameter Declaration List Syntax on page 180
Type Specifiers on page 87
Identifiers on page 58
Block on page 196

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 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 OS/390 C++ compiler
implementation is based on the definition of the language contained in the Draft
Proposal International Standard for Information Systems-Programming Language
C++ (X3J16/92-00091). The OS/390 C++ compiler also supports a subset of the
C++ ANSI/ISO (Draft) Standard (X3J16/93-0062).

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

Chapter 3. Introduction to C and C++

43

Object-Oriented Programming
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 object.
Classes also contain typedefs, enums, and other classes.

Encapsulation
Another key feature of object-oriented programming is encapsulation. Encapsulation
means a class can hide the details of:
v The representation of its data members
v 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:
v Users of a class do not have to deal with unnecessary implementation details.
v Programs are easier to debug and maintain.
v 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 security mechanism. It is possible to circumvent
the class access controls that make encapsulation possible. The language is
not designed to prevent such misuse.

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.

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

44

OS/390 V2R10.0 C/C++ Language Reference

Object-Oriented Programming
a particular function. Application programs can then apply that function to an object
without needing to know the specifics of the class to which the object belongs.
In C++, dynamic binding hides the differences between members of 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.

Other Features of C++


C++ provides several other powerful extensions to the C programming language.
Among these are:
v Constructors and destructors, which are used to initialize and destroy class
objects
v Overloaded functions and operators, which let you extend the operations a
function or operator can perform on different data types
v Inline functions, which can make programs more efficient
v References, which allow a function to modify its arguments in the calling function
v Template functions and classes, which allow the definition of generic classes and
functions
v Object-Oriented Exception handling, which provides transfer of control and
recovery from errors and other exceptional circumstances

C++ Programs
C++ programs contain many of the same programming statements and constructs
as C programs:
v C++ has many of the same fundamental types (built-in) data types as C, as well
as some types that are not built-in to C. For example, packed decimal is
supported in C but not C++.
v Like ANSI/ISO C, C++ allows you to declare new names for existing (perhaps
complex) types by using the typedef construct. These new type names are not
new types.
v In general, the scope and storage class rules for C also apply in C++.1
v C and C++ have the same set of arithmetic and logical operators.
A C++ name can identify any of the following:
v An object
v A function
v A set of functions
v An enumerator

1. Note: There are exceptions, for example, the following is legal C but not C++:

typedef int s;
struct s{
int i;
};
void f(structs,s);

Chapter 3. Introduction to C and C++

45

C++ Programs
v
v
v
v
v

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().
The following is a simple C++ program containing declarations, expressions,
statements, and two functions:

46

OS/390 V2R10.0 C/C++ Language Reference

C++ Programs

CBC3X02D
/**
** A simple C++ program containing declarations,
** expressions, statements, and two functions:
**/
#include <math.h>
// contains definition of fabs()
const double multiplier=2.2;
// variable initialization
const double common_ratio=3.1;
// variable initialization
double geo_series(double a, double r)
// function definition
{
if (r == 1.0)
// if statement
return -1.0;
// return statement
else return -2.0;
};
int main()
// program execution begins here
{
double sum;
// variable declaration
sum = geo_series(multiplier, common_ratio); // function call
// ..
return 0;
}

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:
v Local
v Function
v File
v Class
The scope of a name is determined by the location of the names declaration.
A type name first declared in a function return type has file scope. In the following
example, Y has file scope:
struct Y { int a; int b } foo(int a) { . }

A type name first declared in a function argument list has local scope. In the
following example, X has local scope:
int foo(struct X { int a; int b; } x, int y) {
.
}

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. See Friend Scope on page 303 for more information.

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.

Chapter 3. Introduction to C and C++

47

Scope in C++
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 variable names from the outer block
are usually visible in the nested block. However, if an outer block name 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. See C++ Scope Resolution Operator (::) on page 138 for
infomation on scope resolution.

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.

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.

Class Scope
The name of a class member has class scope and can only be used in the
following cases:
v In a member function of that class
v In a member function of a class derived from that class
v After the . (dot) operator applied to an instance of that class
v After the . (dot) operator applied to an instance of a class derived from that class
v After the -> operator applied to a pointer to an instance of that class
v After the -> (arrow) operator applied to a pointer to an instance of a class
derived from that class
v After the :: (scope resolution) operator applied to the name of a class
v After the :: (scope resolution) operator applied to a class derived from that class.
For more information on class scope, see Scope of Class Names on page 282.

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 OS/390 C/C++ IBM
Open Class Library Reference.

48

OS/390 V2R10.0 C/C++ Language Reference

Input and Output


There are four predefined I/O stream objects that you can use to perform standard
I/O:
v cout
v cin
v cerr
v clog
You can use these in conjunction with the overloaded shift operators, << (insertion
or output) and >> (extraction or input). To use streams and operators, you must
include the header file iostream.h. The following example prints Hello World! to
standard output:

CBC3X02F
/**
** 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.

Output (cout, cerr, and clog)


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

CBC3X02G
/**
** 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 classes.
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.

CBC3X02H
/**
** Check for a division by zero condition.
** If one occurs, a message is sent to standard error.
Chapter 3. Introduction to C and C++

49

Input and Output


**/
#include <iostream.h>
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;
return;
}
cout << "The answer is " << val1 / val2 << endl;
}

Input (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:

CBC3X02I
/**
** 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.

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.

50

OS/390 V2R10.0 C/C++ Language Reference

Linkage Specifications
The syntax is:
%% extern string-literal

declaration
{ '

%&

declaration

The string-literal is used to specify the linkage associated with a particular function.
For example:

CBC3X02J
/**
** This example illustrates linkage specifications
**/
extern "C" int printf(const char*,...);
void main()
{
printf("hello\n");
}

Here the string-literal, "C", tells the C++ compiler that the routine printf(const
char*,...) is a C library function. 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

For more information on string literals, see String Literals on page 66. For linkage
specification information, see the OS/390 C/C++ Programming Guide.
If the value of string-literal is not recognized, C type linkage is used.

Chapter 3. Introduction to C and C++

51

Linkage Specifications

52

OS/390 V2R10.0 C/C++ Language Reference

Chapter 4. Lexical Elements of C and C++


This chapter describes the following lexical elements of C and C++:
v Tokens
v Source Program Character Set
v Comments on page 56
v Identifiers on page 58
v Constants on page 61

Tokens
During preprocessing and compilation, OS/390 C/C++ treats source code as a
sequence of tokens. There are five different types of tokens:
v Identifiers
v Keywords
v Literals
v Operators
v Other separators
You should separate adjacent identifiers, keywords, and literals with white space.
You should separate other tokens by white space to make the source code more
readable. White space includes blanks, horizontal and vertical tabs, new lines, form
feeds, and comments.

Source Program Character Set


The following lists the basic character set that must be available at both compile
and run time:
v The uppercase and lowercase letters of the English alphabet
a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

v The decimal digits 0 through 9


0 1 2 3 4 5 6 7 8 9

v The following graphic characters:


! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] _ { }

v The caret (|) character in ASCII (bitwise exclusive OR symbol), which may be
represented by the equivalent not () character on EBCDIC systems
v The split vertical bar () character in ASCII, which you may represent by the
vertical bar (|) character on EBCDIC systems
v The space character
v The control characters that represent new-line, horizontal tab, vertical tab, and
form feed, and end of string (NULL character).
OS/390 C/C++ uses the number sign (#) character for preprocessing only, and
treats the _ (underscore) character as a normal letter.
The execution character set also includes control characters that represent alert,
backspace, carriage return, and new-line.
In a source file, a record contains one line of source text; the end of a record
indicates the end of a source line.
Copyright IBM Corp. 1996, 2000

53

Character Set
The encoding of the following characters from the basic character set may vary
between the source-code generation environment and the runtime environment:
! # [ ] \ { } | |

The OS/390 C/C++ compiler normalizes the encoding of source files indicated by
the #pragma filetag directive and the LOCALE compile time option to the encoding
defined by code page 1047.
The compiler uses the character set that is specified for the LOCALE option for any
output. This includes:
v Listings that contain identifier names and source code
v String literals and character constants that are emitted in the object code
v Messages generated by the compiler
However, this does not include the source-code annotation in the pseudo-assembly
listings.
Depending on the EBCDIC encoding that your installation uses, you can express
the | and | characters as and respectively. This book refers to the | and |
symbols as the caret and vertical bar, respectively. If you do not specify the
NOLOCALE compile-time option, OS/390 C/C++ does not perform normalization. It
assumes that the character set encoding is the IBM-1047 code page. In this case, it
recognizes both the broken and unbroken vertical bars as the vertical bar. The caret
and logical not sign are recognized as the caret. For a detailed description of the
#pragma filetag directive and the LOCALE option, refer to the description of
internationalization, locales, and character sets in the OS/390 C/C++ Programming
Guide.
The compiler recognizes and supports the additional characters (the extended
character set) which you can meaningfully use in string literals and character
constants. The support for extended characters includes the multibyte character
sets.
OS/390 systems represent multibyte characters by using Shiftout <SO> and Shiftin
<SI> pairs. Strings are of the form:
<SO> x y z <SI>

Or they can be mixed:


<SO> x <SI> y z
x <SO> y <SI> z

In the above, two bytes represent each character between the <SO> and <SI>
pairs. OS/390 C/C++ restricts multibyte characters to character constants, string
constants, and comments.
Refer to the OS/390 C/C++ Run-Time Library Reference for a discussion on strings
that are passed to library routines, and to Character Constants on page 65 of this
book for information on character constants. If you specify a lowercase a as part of
an identifier name, you cannot substitute an uppercase A in its place. You must use
the lowercase letter.

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 by using a sequence of three
characters that are called a trigraph. The trigraph sequences are:

54

OS/390 V2R10.0 C/C++ Language Reference

Character Set
??=
??(
??)
??<
??>
??/
??
??!
??-

#
[
]
{
}
\
|
|

number 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 by using the code page that is indicated by the
LOCALE option. If you do not specify the LOCALE option, the preprocessor uses code
page 1047.
At compile time, the compiler translates the trigraphs found in string literals and
character constants into the appropriate characters they represent. These
characters are in the coded character set you select by using the LOCALE compiler
option.
Note: The OS/390 C/C++ compiler will compile source files that were edited using
different encoding of character sets. However, they might not compile
cleanly. OS/390 C/C++ does not compile source files that you edit with the
following:
v A character set that does not support all the characters that are specified
above, even if the compiler can access those characters by a trigraph.
v A character set for which no one-to-one mapping exists between it and the
character set above.
Note: The exclamation mark (!) is a variant character. Its recognition depends on
whether or not the LOCALE option is active. For more information on variant
characters, refer to the OS/390 C/C++ Programming Guide.

Example
some_array??(i??) = n;

Represents:
some_array[i] = n;

Digraph Characters
|
|
|

You can represent unavailable characters in a C or C++ source program by using a


combination of two keystrokes that are called a digraph character. The
preprocessor reads digraphs as tokens during the preprocessor phase.
The digraph characters are:

%: or %%
<:
:>
<%
%>
%:%: or
%%%%

#
[
]
{
}
##

number sign
left bracket
right bracket
left brace
right brace
preprocessor macro concatenation operator

Chapter 4. Lexical Elements of C and C++

55

Character Set
You can create digraphs by using macro concatenation. OS/390 C/C++ does not
replace digraphs in string literals or in character literals. For example:
char *s = "<%%>"; // stays "<%%>"
switch (c)
{
case '<%' : { /* ... */ } // stays '<%'
case '%>' : { /* ... */ } // stays '%>'
}

The NODIGRAPH option disables processing of digraphs. The NODIGRAPH option is on


by default.
The DIGRAPH option is described in the OS/390 C/C++ Users Guide.

Additional Keywords (C++ only)


If you use the digraph option, you can represent unavailable characters in a C++
source program by using the following keywords:
Keyword

Symbol

bitand

&

and

&&

bitor

or

||

xor

compl

and_eq

&=

or_eq

|=

xor_eq

|=

not

not_eq

!=

These keywords are only reserved in C++ programs that are compiled with the
DIGRAPH option. OS/390 C/C++ Users Guide describes the DIGRAPH option.

Comments
Comments begin with the /* characters. They end with the */ characters, and can
span more than one line. You can put comments anywhere the language allows
white space.
The preprocessor replaces comments during preprocessing by a single space
character.
Multibyte characters can also be included within a comment.
Note: The /* or */ characters that are found in a character constant or string literal
do not start or end comments.
In the following program, line 6 is a comment:

56

OS/390 V2R10.0 C/C++ Language Reference

Comments
1
2
3
4
5
6
7
8

#include <stdio.h>
int main(void)
{
printf("This program has a comment.\n");
/* printf("This is a comment line and will not print.\n"); */
return 0;
}

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
2
3
4
5
6
7
8

#include <stdio.h>
int main(void)
{
printf("This program does not have \
/* NOT A COMMENT */ a comment.\n");
return 0;
}

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 */.
The following example highlights the comments:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

/* A program with nested comments. */


#include <stdio.h>
int main(void)
{
test_function();
return 0;
}
int test_function(void)
{
int number;
char letter;
/*
number = 55;
letter = 'A';
/* number = 44; */
*/
return 999;
}

In test_function, the compiler reads the /* in line 15 through the */ in line 18 as a


comment. It reads the comment at line 19 as C language code which causes errors
at that line. To avoid commenting over comments already in the source code, you
should use conditional compilation preprocessor directives to cause the compiler to
bypass sections of a program. For example, instead of commenting out the above
statements, change line 2 and lines 15 to 19 in the following way:
2

#define TEST_FUNCTION 0
...
16 #if TEST_FUNCTION
Chapter 4. Lexical Elements of C and C++

57

Comments
17
18
19
20

number = 55;
letter = 'A';
/*number = 44;*/
#endif /*TEST_FUNCTION */

Chapter 10. Preprocessor Directives on page 215 describes conditional


compilation preprocessor directives. You can include multibyte characters with a
comment.

C++ Comments
If the SSCOMM compiler option is in effect when you compile a C program, double
slashes (//) also specify the beginning of a comment. 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. You can represent the
backslash character with a trigraph.

Identifiers
An arbitrary number of letters or digits comprise an identifier. Identifiers provide
names for the following language elements:
v Functions
v Data objects
v Labels
v Tags
v Parameters
v Macros
v Typedefs
v Structure and union members
An identifier has the form:

%%

letter
_
$

'

letter
digit
_
$

%&

Special Characters in Identifiers


The first character in an identifier must be a letter or the underscore (_) character.
The compiler reserves identifiers beginning with an underscore, however, for
identifiers at file scope.
Identifiers that begin with two underscores or an underscore that is followed by a
capital letter, are reserved in all contexts.
Avoid creating identifiers that begin with an underscore for function names and
variable names.
At the extended and compatible language levels, C++ identifiers can contain the $
character. At the ANSI language level, identifiers can begin with the underscore but
not with a $ (dollar sign).

58

OS/390 V2R10.0 C/C++ Language Reference

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

Case Sensitivity in Identifiers


The compiler distinguishes between uppercase and lowercase letters in identifiers.
For example, PROFIT and profit represent different objects.
Note: If you do not use the OS/390 C compiler long name support, you may
receive an error message if you use either STOCKONHOLD and stockonhold as
external identifiers. For more information on long name support, see
longname on page 258. For more information on the binder and the
prelinker, see the OS/390 C/C++ Users Guide. Also see OS/390 C/C++
External Name Mapping on page 60 and OS/390 Long Name Support on
page 60.

Significant Characters in Identifiers


In general, OS/390 C/C++ truncates external and internal identifiers after 1024
characters. However, the C compiler truncates external identifiers after 8 characters
if the NOLONGNAME compile-time option is in effect. Also, the C++ compiler truncates
external identifiers that do not have C++ linkage after 8 characters if the NOLONGNAME
compile-time option is in effect.

Keywords
Keywords are identifiers that are 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 table lists the keywords common to both the C and C++
languages. The ANSI/ISO C language definition includes these keywords:
Table 3. Keywords Common to C and C++
auto
break
case
char
const
continue
default
do

double
else
enum
extern
float
for
goto
if

int
long
register
return
short
signed
sizeof
static

struct
switch
typedef
union
unsigned
void
volatile
while

The C++ language also reserves the following keywords:


Table 4. C++ Keywords
asm
__cdecl
catch
class
delete

_Export
friend
inline
new
operator

private
protected
public
template
this

throw
try
virtual
wchar_t

Future versions of the C++ compiler may reserve the following keywords, so you
should avoid using them in your applications:
Chapter 4. Lexical Elements of C and C++

59

Identifiers
Table 5. C++ Keywords (Future)
bool
const_cast
dynamic_cast
explicit

false
mutable
namespace

reinterpret_cast
static_cast
true

typeid
typename
using

The C compiler reserves the __Packed keyword.

OS/390 C/C++ External Name Mapping


OS/390 C/C++ maps the names of variables or functions that have external
linkages to names that are used in the object module. When you compile an
OS/390 C/C++ program, refer to the following guidance for using names of
variables or functions with external linkage:
v Do not use names of the library functions for user-defined functions.
v Some functions in the C library and C runtime environment begin with two
underscores (_ _). Do not use an underscore as the first letter of an identifier.
v The compiler maps each underscore to an at sign (@) for external names without
C++ linkage, except when you compile a program with the LONGNAME compile-time
option. In that case, the underscore remains as an underscore.
v IBM-provided functions have names that begin with IBM, CEE, and PLI. Avoid
using these names as the OS/390 C/C++ compiler changes these names to
prevent conflicts between runtime functions and user-defined names. It changes
all static or extern variable names that begin with IBM, CEE, and PLI in your
source program to IB$, CE$, and PL$, respectively, in the object module. If you
are using interlanguage calls, avoid using these prefixes. The compiler of the
calling or called language may or may not change these prefixes in the same
manner as the OS/390 C/C++ compiler does. All of this is completely integrated
into the OS/390 C/C++ compiler, Debug Tool, and LE/370.
To call an external program or access an external variable that begins with IBM,
CEE, and PLI, use the #pragma map preprocessor directive. The following is an
example of #pragma map that forces an external name to be IBMENTRY.
#pragma map(ibmentry,"IBMENTRY")

For more information on the #pragma map directive, see map on page 259.

OS/390 Long Name Support


If you do not specify the LONGNAME option when you compile your code with the C
compiler, the compiler maps an underscore to an at sign. It also truncates external
names to 8 characters and changes them to uppercase. The C++ compiler makes
the same changes to external identifiers that do not have C++ linkage if you do not
specify the LONGNAME option.
For example, consider if you compile the following C program and do not specify
the LONGNAME option:
int test_name[4] = { 4, 8, 9, 10 };
int test_namesum;
int main(void) {
int i;
test_namesum = 0;

60

OS/390 V2R10.0 C/C++ Language Reference

Identifiers

for (i = 0; i < 4; i++)


test_namesum += test_name[i];
printf("sum is %d\n", test_namesum);

In the above example, the C compiler displays the following message:


ERROR

CBC3244 ./sum.c:2

External name TEST_NAM cannot be redefined.

The compiler changes the external names test_namesum and test_name to


uppercase and truncates them to 8 characters. If you specify the CHECKOUT
compile-time option, the compiler will generate two informational messages to this
effect. Because the truncated names are now the same, the compiler produces an
error message and terminates the compilation.
If you compile the previous program with the LONGNAME compile-time option, the
compiler does not produce any warning or error messages. However, if you specify
the LONGNAME option, you must bind your program with the binder to produce a
program object in a PDSE. Otherwise you must use the prelinker.
The LONGNAME compile-time option supports mixed case, external names of up to
1024 characters for OS/390 C/C++ programs.
Object modules that are produced by compiling with LONGNAME have external names
that are mixed case and up to 1024 characters long. Object modules that are
produced by compiling with NOLONGNAME have uppercase external names that are
limited to a length of 8 characters.
To use external C names that are longer than 8 characters or external C++ names
without C++ linkage that are longer than 8 characters, you can, in your source
code:
v Use the #pragma map directive to map long external names in the source code to
8 or less characters in the object module.
#pragma map(verylongname,"sname")

v Use the long name support that is provided by the compile-time option LONGNAME.
To use the long name support, you must do the following:
Use the LONGNAME compile-time option when compiling your program.
Use the binder to produce a program object in a PDSE, or use the prelinker.
For more information on the binder, prelinker, and LONGNAME compile-time
option, see the OS/390 C/C++ Users Guide.

Constants
A constant does not change its value while the program is running. The value of
any constant must be in the range of non-negative representable values for its type.
C/C++ contains the following types of constants (also called literals):
v Integer
v Floating-Point
v Fixed-Point Decimal Constants (C Only)
v Character
v String
v Enumeration

Chapter 4. Lexical Elements of C and C++

61

Constants
Enumerations on page 91 discusses enumeration constants, which belong to the
lexical class of identifiers. For more information on data types, see Type Specifiers
on page 87.

Integer Constants
Integer constants represent integer values. You can represent integer constants in
decimal, hexadecimal, or octal values.
%%

decimal_constant
octal_constant
hexadecimal_constant

l
L
u
U

%&
l

u
U

L
l
L

l
L

Note that the suffixes in the above syntax diagram are not case-sensitive; that is, l
and L are the same to the compiler.
An integer constant without a suffix cannot have a value greater than ULONG_MAX. An
integer constant with a suffix that contains LL cannot have a value greater than
ULONGLONG_MAX. In these cases, the compiler will issue an out of range error
message. For information on the ULONG_MAX and the ULONGLONG_MAX macros, see the
OS/390 C/C++ Run-Time Library Reference.

Data Types for Integer Constants


OS/390 C/C++ determines the data type of an integer constant 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 compiler uses the smallest data type
that can represent the constant value to store the constant.
Table 6. Data Types for Integer Constants
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

suffixed by ll or LL

long long int

suffixed by both u or U, and ll or LL

unsigned long long int

A plus (+) or minus (-) symbol can precede an integer constant. OS/390 C/C++
treats it as a unary operator rather than as part of the constant value.

62

OS/390 V2R10.0 C/C++ Language Reference

Constants

Decimal Constants

A decimal constant contains any of the digits 0 through 9. The first digit cannot be 0.

%% digit_1_to_9 '

digit_0_to_9

%&

OS/390 C/C++ interprets integer constants that begin with the digit 0 as an octal
constant, rather than as a decimal constant.
The following are examples of decimal constants:
485976
-433132211
+20
5

Hexadecimal Constants

A hexadecimal constant begins with the 0 digit that is followed by either an x or X.


This is 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.

%%

0x
0X

'

digit_0_to_f
digit_0_to_F

%&

The following are examples of hexadecimal constants:


0x3b24
0XF96
0x21
0x3AA
0X29b
0X4bD

Octal Constants

An octal constant begins with the digit 0 and contains any of the digits 0 through 7.

%% 0 ' digit_0_to_7

%&

The following are examples of octal constants:


0
0125
034673
03245

Floating-Point Constants
A floating-point constant consists of following parts:
v An integral part
v A decimal point
Chapter 4. Lexical Elements of C and C++

63

Constants
v A fractional part
v An exponent part
v 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.

'

%%

. '

digit
' digit

' digit

digit

exponent

exponent

f
F
l
L

exponent

Exponent:

e
E

+
-

' digit

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.
The suffix f or F indicates a type of float, and the suffix l or L indicates a type of
long double. If you do not specify a suffix, the floating-point constant has a type
double.
A plus (+) or minus (-) symbol can precede a floating-point constant. The compiler
treats it as a unary operator rather than as part of the constant value.
The following are examples of floating-point constants:

64

Floating-Point Constant

Value

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

OS/390 V2R10.0 C/C++ Language Reference

%&

Constants

Fixed-Point Decimal Constants (C Only)


Fixed-point decimal constants are an IBM extension to ANSI/ISO C. This type is
available when you specify the LANGLVL(EXTENDED) compile-time option.
A fixed-point decimal constant has a numeric part and a suffix that specifies its
type. The numeric part can include a digit sequence that represents the
whole-number part, followed by a decimal point (.), followed by a digit sequence
that represents the fraction part. Either the integral part or the fractional part, or
both must be present.
A fixed-point constant has the form:

%%

'

digit_0_to_9

D
d

' digit_0_to_9

' digit_0_to_9

'

%&

digit_0_to_9

' digit_0_to_9

A fixed-point constant has two attributes:


Number of digits (size)
Number of decimal places (precision).
The suffix D or d indicates a fixed-point constant.
The following are examples of fixed-point decimal constants:
Fixed-Point Constant

(size, precision)

1234567890123456D
12345678.12345678D
12345678.d
.1234567890d
12345.99d
000123.990d
0.00D

(16,
(16,
( 8,
(10,
( 7,
( 9,
( 3,

0)
8)
0)
10)
2)
3)
2)

For more information on fixed-point decimal data types, see the OS/390 C/C++
Programming Guide.

Character Constants
A character constant contains a sequence of characters or escape sequences that
are enclosed in single quotation mark symbols.

Chapter 4. Lexical Elements of C and C++

65

Constants

%%

'

'

character
escape_sequence

'

%&

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 that contains a single character is the numeric
representation of the character in the character set that is used at compile 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 has type wchar_t, and is used to represent multibyte
characters. Multibyte characters represent characters that use more than one byte
for their encoding. Each multibyte character requires up to 4 bytes for its encoding.
You can represent the double quotation mark symbol by itself. You must, however,
use the backslash symbol that is followed by a single quotation mark symbol (\') as
an escape sequence to represent the single quotation mark symbol.
You can represent the new-line character by the \n new-line escape sequence. You
can represent the backslash character by the \\ backslash escape sequence.
The following are examples of character constants:
'a'
'0'
'x'
'7'
'C'

'\''
'('
'\n'
'\117'

String Literals
A string constant or literal contains a sequence of characters or escape sequences
that are enclosed in double quotation mark symbols.
The maximum size of a string literal on OS/390 C/C++ is 32,765 bytes.

%%

"

'

character
escape_sequence

"

The prefix L indicates a wide-character string literal.

66

OS/390 V2R10.0 C/C++ Language Reference

%&

Constants
OS/390 C/C++ appends a null ('\0') character 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.
The compiler retains multiple spaces that are contained within a string constant.
To continue a string on the next line, you can use two or more consecutive strings.
The compiler concatenates adjacent string literals to produce a single string. You
cannot concatenate a wide string constant with a character string constant. For
example:
"hello " "there"
"hello " L"there"
"hello" "there"

/* is equivalent to "hello there"


/* is not valid
/* is equivalent to "hellothere"

*/
*/
*/

Another way to continue a string is to use the line continuation sequence (\ symbol
that is 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.

*/
*/
*/

Characters in concatenated strings remain distinct. For example, the string \xab
occupies 2 bytes of storage. The first byte contains the value X'ab', and the second
byte contains the value X'00' which is the trailing null character. The string \xa\xb
occupies 3 bytes of storage that contains the values X'0a', X'0b', and X'00'.
Following any concatenation, OS/390 C/C++ appends a '\0' of type char at the
end of each string. C++ library functions find the end of a string by scanning for this
value. For a wide-character string literal, OS/390 C/C++ appends a '\0' of type
wchar_t. For example:
char *first = "Hello ";
char *second = "there";
char *third = "Hello " "there";

/* stored as "Hello \0"


*/
/* stored as "there\0"
*/
/* stored as "Hello there\0" */

A character string constant has type array of char and static storage duration. A
wide character string constant has type array of wchar_t and static storage duration.
You should be careful when modifying string literals because the resulting behavior
depends on whether your strings are stored in read/write static memory. C strings
are read/write by default. C++ strings are readonly by default.
Use the #pragma strings directive to change the default storage for string literals.
strings on page 271 describes the #pragma strings directive.
OS/390 C/C++ stores string literals in static storage which can be modified like any
other storage location. C/C++ has the concept of readonly and writeable strings.
This deals with how C/C++ stores multiple occurrences of strings, rather than
whether or not you can modify the strings.
When a string literal appears more than once in the program source, how that string
is stored depends on whether strings are readonly or writeable. If strings are
readonly, then OS/390 C/C++ allocates only one location for that string. All
occurrences will refer to that one location. If strings are writeable, then each
occurrence of the string will have a separate, distinct storage location.
Chapter 4. Lexical Elements of C and C++

67

Constants
By default, the C compiler will consider strings to be writeable. Note that for
readonly #pragma strings, the compiler will put literal strings in an area of storage
that is potentially read only. For writable #pragma strings, it will put them in an area
of storage that is always modifiable.
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:

CBC3X02K
/**
** 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 ".

Escape Sequences
You can represent any member of the execution character set by an escape
sequence. You can use escape sequences to put unprintable characters in
character and string literals. For example, you can use escape sequences to put
such characters as tab, carriage return, and backspace into an output stream.
%% \

escape_sequence_character
x hexadecimal_digits
octal_digits

%&

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). The value of
the hexadecimal or octal number specifies the value of the desired character or
wide character.
Note: The line continuation sequence (\ followed by a new-line character) is not an
escape sequence. You can use it in character strings to indicate that the
current line continues on the next line.

68

OS/390 V2R10.0 C/C++ Language Reference

Constants
The escape sequences and the characters they represent are:
Escape Sequence

Character Represented

\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 code point of the code page you
use at run time. OS/390 C/C++ translates escape sequences during preprocessing.
For example, on a system that uses the ASCII character codes, the value of the
escape sequence \x56 is the letter V. On a system that uses EBCDIC character
codes, the value of the escape sequence \xE5 is the letter V.
Use escape sequences only in character constants or in string literals. OS/390
C/C++ issues a message only if it does not recognize an escape sequence.
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:

CBC3X02L
/** CBC3X02L
** This example illustrates escape sequences
**/
#include <iostream.h>
void main()
{
char a,b,c,d,e;
a='a';
b=129;
// EBCDIC integer value
c='\201';
// EBCDIC octal value
d='\x81';
// EBCDIC hexadecimal value
e='\n';
cout << a << b << c << d << e;
}

Chapter 4. Lexical Elements of C and C++

69

Constants

70

OS/390 V2R10.0 C/C++ Language Reference

Chapter 5. 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, OS/390 C/C++ does not
allocate storage. This chapter discusses the following topics on declarations:
v Declarations Overview
v Block Scope Data Declarations on page 72
v File Scope Data Declarations on page 73
v
v
v
v
v

Objects on page 74
Storage Class Specifiers on page 74
typedef on page 85
Type Specifiers on page 87
Declarators on page 121

v Initializers on page 129


v C/C++ Data Mapping on page 131
v C++ Function Specifiers on page 131
v C++ References on page 131

Declarations Overview
Declarations determine the following properties of data objects and their identifiers:
v Scope, which describes the visibility of an identifier in a block or source file. For
a complete description of scope, see Scope in C on page 37.
v Linkage, which describes the association between two identical identifiers. See
Program Linkage on page 38 for more information.
v Storage duration, which describes when the system allocates and frees storage
for a data object. See Storage Duration on page 40 for more information.
v Type, which describes the kind of data the object is to represent.
The lexical order of elements when you declare a data object is as follows:
v Storage duration and linkage specification, that are described in Storage Class
Specifiers on page 74
v Type specification, described in Type Specifiers on page 87
v Declarators, which introduce identifiers and make use of type qualifiers and
storage qualifiers, described in Declarators on page 121
v Initializers, which initialize storage with initial values, described in Initializers on
page 129.
Chapter 8. Functions on page 173 describes function declarations.
All data declarations have the form:

Copyright IBM Corp. 1996, 2000

71

Declarations Overview
,
%% '

storage_class_specifier
type_specifier
type_qualifier

' declarator

initializer

%&

C++ Notes:
1. One of the fundamental differences between C++ and C is the placement of
variable declarations. Although you can declare variables in the same way, in
C++, you can put variable declarations 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 you never call a
function and never take its address, then you do not have to define it. If you
declare an object, but never use it, or use it only 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. The identifiers
that are declared in the first column do not allocate storage; they refer to a
corresponding definition. In the case of a function, the corresponding definition is
the code or body of the function. The identifiers that are declared in the second
column allocate storage; they are both 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;

Block Scope Data Declarations


You can only put a block scope data declaration 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 one of the following
storage class specifiers:

72

OS/390 V2R10.0 C/C++ Language Reference

Block Scope Data Declarations


v
v
v
v

auto
register
static
extern

If you do not specify a storage class specifier in a block-scope data declaration,


OS/390 C/C++ uses the default storage class specifier auto. 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 that is 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 on
page 74 for details on the different storage classes.

Storage
The duration and type of storage vary 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
v
v
v
v
v
v
v
v

Declarators on page 121


Storage Class Specifiers on page 74
auto Storage Class Specifier on page 75
extern Storage Class Specifier on page 77
register Storage Class Specifier on page 83
static Storage Class Specifier on page 83
Initializers on page 129
Type Specifiers on page 87

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
OS/390 C/C++ to allocate storage 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 and extern. All file scope variables that are defined with static storage
class have internal linkage; other file scope variables have external linkage. If you
specify the storage class, you can omit the type specifier. If you omit the type
specifier, all variables that are defined in that declaration receive the type int.

Chapter 5. Declarations

73

File Scope Data Declarations

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, a
constant expression must describe the initializer. Otherwise, it must reduce to the
address of a previously declared variable at file scope, possibly added to 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. OS/390
C/C++ allocates storage at run time which it frees when the program stops running.

Related Information
v
v
v
v

extern Storage Class Specifier on page 77


static Storage Class Specifier on page 83
Initializers on page 129
Type Specifiers on page 87

Objects
An object is a region of storage that contains a value or group of values. You can
access each value by using its identifier or by using a complex expression that
refers to the object. In addition, each object has a unique data type. OS/390 C/C++
establishes both the identifier and data type of an object 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. You can also use it
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, you reference objects by variables or references. A variable also
represents the location in storage that contains the value of an object.
You commonly refer to an instance of a class type as a class object. The individual
data members of an instantiated class object are also called objects. The set of all
member objects comprises a class object.

Storage Class Specifiers


The storage class specifier you use within the declaration determines whether:
v The object has internal, external, or no linkage.
v The object is stored in memory or in a register, if available.
v The object receives the default initial value 0 or an indeterminate default initial
value.
v The object is referenced throughout a program or only within the function, block,
or source file where you have defined the variable.

74

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers


v The storage duration for the object is static or automatic. For static, OS/390
C/C++ maintains storage throughout the program run time. For automatic,
OS/390 C/C++ maintains storage 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 duration. 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.
This section describes the following storage class specifiers:
v auto
v extern
v register
v static

auto Storage Class Specifier


The auto storage class specifier lets you define a variable with automatic storage.
OS/390 C/C++ restricts its use and storage to the current or contained block. The
storage class keyword auto is optional in a data declaration. You cannot use it in a
parameter declaration. You must declare a variable that has the auto storage class
specifier within a block. You cannot use it for file scope declarations.
Automatic variables require storage only while the function in which they are
declared is active. Consequently, defining variables with the auto storage class can
decrease the amount of memory that is 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. A change to an auto variable in one function never affects another
function (unless you pass it as an argument).

Initialization

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 that represents 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 you use an initializer list. Each time an objects definition (auto or
register) is encountered during program execution, its initialization, if any, is done.
Note: If you use the goto statement to jump into the middle of a block, automatic
variables defined before the label that is jumped to are not initialized.

Storage

Objects with the auto storage class specifier have automatic storage duration. Each
time a block is entered, storage for auto objects that are defined in that block is
made available. When the block is exited, the objects are no longer available for
use.
Chapter 5. Declarations

75

Storage Class Specifiers


If you define an auto object within a function that you invoke recursively, OS/390
C/C++ allocates memory for the object at each invocation of the block.

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 that is created by the second
definition is available. During the rest of the program, only the auto_var that is
created by the first definition is available.
CBC3RAAF:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

/****************************************************
** Example illustrating the use of auto variables **
****************************************************/
#include <stdio.h>
int main(void)
{
void call_func(int passed_var);
auto int auto_var = 1; /* first definition of auto_var
{

*/

int auto_var = 2;
/* second definition of auto_var */
printf("inner auto_var = %d\n", auto_var);

}
call_func(auto_var);
printf("outer auto_var = %d\n", auto_var);
return 0;

void call_func(int passed_var)


{
printf("passed_var = %d\n", passed_var);
passed_var = 3;
printf("passed_var = %d\n", passed_var);
}

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.
CBC3RAAG:
/*****************************************************************
** 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);

76

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers


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 you run the program, interaction with the program could produce:
Output

Enter letters:

Input

zyfab

Output

The sorted string is: abfyz

Related Information

v
v
v
v

Block Scope Data Declarations on page 72


register Storage Class Specifier on page 83
Address (&) on page 145
Function Declarator on page 180

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 describes the variable
that is externally defined.
If a declaration for an identifier already exists at file scope, any extern declaration
of the same identifier that is 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.
Chapter 5. Declarations

77

Storage Class Specifiers


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.
If you do not specify a storage class specifier, the function has external linkage. It is
an error to include a declaration for the same function with the storage class
specifier static before the declaration with no storage class specifier because of
the incompatible declarations. Including the extern storage class specifier on the
original declaration is valid, and the function has internal linkage.
In OS/390 C++, you can declare functions with the following:
Linkage

By specifying

extern "C"

C++

extern "C++

OS

extern "OS"

PLI

extern "PLI"

builtin

extern "builtin"

COBOL

extern "COBOL"

FORTRAN

extern "FORTRAN"

|
|

OS_DOWNSTACK
extern "OS_DOWNSTACK"

|
|

OS_UPSTACK

|
|

OS_NOSTACK

|
|

OS31_NOSTACK
extern "OS31_NOSTACK"

REFERENCE

extern "OS_UPSTACK"
extern "OS_NOSTACK"

extern "REFERENCE"

There are some limitations to using extern to specify non-C++ linkage for a
function. While the C++ language supports overloading, other languages do not.
The implications of this are:
v You cannot overload a function that has non-C++ linkage:
extern "FORTRAN"{int func(int);}
extern "FORTRAN"{int func(int,int);}

// not allowed-compiler
// will issue an error message

v You cannot declare a function with a linkage specification if you have already
used the same function name in a declaration without a linkage specification:
int func(int);
extern "FORTRAN"{int func(int,int);}

// not allowed-compiler
// will issue an error message

v You can overload a function as long as it has C++ (default) linkage. Therefore,
OS/390 C/C++ allows the following series of statements:
extern "FORTRAN"{int func(int,int);}
int func(int);
// function with C++ linkage
int func(int,int);
// overloaded function with C++ linkage

v You cannot redefine a function that has a linkage specification:

78

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers


extern func(int);
extern "FORTRAN"{int func(int,int);}

// not allowed-compiler
// will issue an error message

For more information, see Using Linkage Specifications in C++ in the OS/390
C/C++ Programming Guide, or refer to OS/390 Language Environment Writing
Interlanguage Applications.
The following fragments illustrate the use of extern "C":
extern "C" int cf();

//declare function cf to have C linkage

extern "C" int (*c_fp)(); //declare a pointer to a function,


// called c_fp, which has C linkage
extern "C" {
typedef void(*cfp_T)(); //create a type pointer to function with C
// linkage
void cfn();
//create a function with C linkage
void (*cfp)();
//create a pointer to a function, with C
// linkage
}

Linkage compatibility affects all C library functions that accept a user function
pointer as a parameter. Use the extern "C" linkage specification to ensure that the
declared linkages are the same. An example of these library functions is qsort();
refer to the OS/390 C/C++ Run-Time Library Reference for more information.
The following example fragment uses extern "C" with qsort().
#include <stdlib.h>
// function to compare table elements
extern "C" int TableCmp(const void *, const void *); // C linkage
extern void * GenTable();
// C++ linkage
void main() {
void *table;

table = GenTable();
// generate table
qsort(table, 100, 15, TableCmp); // sort table, using TableCmp
// and C library routine qsort();

C++ Note: In C++, an extern declaration cannot appear in class scope.

Initialization

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 do either of the
following:
v Appear as part of the definition and the initial value must be described by a
constant expression.
v Reduce to the address of a previously declared object with static storage
duration. You can modify this object 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.

Chapter 5. Declarations

79

Storage Class Specifiers

Storage

extern objects have static storage duration. OS/390 C/C++ allocates memory for
extern objects before the main function begins running. When the program finishes
running, OS/390 C/C++ frees the storage.

Controlling External Static

Certain program variables with the extern storage class may be constant and never
be updated. If this is the case, it is not necessary to have a copy of these variables
made for every user of the program. In addition, there may be a need to share
constant program variables between C and another language.

Examples of extern Storage Class


The following program fragment shows how to force an external program variable to
be part of a program that includes executable code and constant data. It uses the
#pragma variable(varname, NORENT) directive:
#pragma variable(rates, NORENT)
extern float rates[5] = { 3.2, 83.3, 13.4, 3.6, 5.0 };
extern float totals[5];
int. main(void) {
.
.
}

In this example, you compile the source file with the RENT option. The executable
code includes the variable rates as you specify the #pragma variable(rates,
NORENT). The writable static includes the variable totals. Each user has a personal
copy of the array totals, and all users of the program share the array rates. This
sharing may yield a performance and storage benefit.
The #pragma variable(varname, NORENT) does not apply to, and has no effect on,
program variables with the static storage class. OS/390 C/C++ always includes
program variables with the static storage class with the writable static. An
informational message appears if you write to a nonreentrant variable when you
specify the C CHECKOUT compile-time option.
When you specify #pragma variable(varname, NORENT) for a variable, ensure that
your program never writes to this variable. Program exceptions or unpredictable
program behavior may result should this be the case. In addition, you must include
#pragma variable(varname, NORENT) in every source file where you reference or
define the variable.
For more information on the RENT and NORENT compile-time options, refer to the
OS/390 C/C++ Users Guide.
The following program shows the linkage of extern objects and functions. It
declares the extern object total 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 example defines
extern function tally 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.

80

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers


CBC3RAH1 (File 1):
1
2
3
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

/**************************************************************
** The program receives the price of an item, adds the
**
** tax, and prints the total cost of the item.
**
**************************************************************/
#include <stdio.h>
int main(void)
{
void tally(void);
extern float total;

/* begin main
*/
/* declaration of function tally */
/* first declaration of total
*/

printf("Enter the purchase amount: \n");


tally();
printf("\nWith tax, the total is: %.2f\n", total);
}

return(0);

/* end main

*/

CBC3RAH2 (File 2):


1
2
3
4
6
7
8
9
10
11
12
13
14
15
16

/**************************************************************
** This file defines the function tally
**
**************************************************************/
#include <stdio.h>
#define tax_rate 0.05
void tally(void)
{
float tax;
extern float total;

/* begin tally */
/* second declaration of total

scanf("%f", &total);
tax = tax_rate * total;
total += tax;

*/

/* end tally */

CBC3RAH3 (File 3):


1

float total;

When you run this program and interaction with it, it could produce the following:
Output

Enter the purchase amount:

Input

99.95

Output

With tax, the total is: 104.95

The following program shows extern variables that are used by two functions. Both
functions main and sort can access and change the values of the extern variables
string and length. Consequently, main does not have to pass parameters to sort.

Chapter 5. Declarations

81

Storage Class Specifiers


CBC3RAAI:
/*****************************************************************
** 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 you run this program, interacting with it could produce the following:
Output

Enter letters:

Input

zyfab

Output

The sorted string is: abfyz

The following code fragment shows a static variable var1, which gets 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;

Related Information

v
v
v
v

82

File Scope Data Declarations on page 73


Constant Expressions on page 139
Function Definitions on page 178
Function Declarator on page 180

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers

register Storage Class Specifier


The register storage class specifier marks heavily used objects (such as loop
control variables). It indicates that the compiler should try to minimize access time
to the object by placing its value in a machine register, if possible. Because of the
limited size and number of registers available on OS/390 systems, few variables
can actually be put in registers. The object is treated as having the storage class
specifier auto.
OS/390 C/C++ requires the register storage class specifier in a block-scope data
definition. It also requires it in a parameter declaration that describes an object that
has the register storage class. You must define an object that has the register
storage class specifier within a block. Or, you must declare it as a parameter to a
function.

Initialization

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 that represents 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 you use an initializer list. The program then sets the object to that
initial value each time it enters the program block that contains the objects
definition.

Storage

Objects with the register storage class specifier have automatic storage duration.
Each time a block is entered, storage for register objects that are defined in that
block is 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 you invoke recursively, OS/390
C/C++ allocates the memory for the variable at each invocation of the block.

Restrictions

You cannot use the register storage class specifier in data scope declarations.
C++ Notes: 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

v
v
v
v

Block Scope Data Declarations on page 72


auto Storage Class Specifier on page 75
Address (&) on page 145
Parameter Declaration List Syntax on page 180

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.
You can define an object that has the static storage class specifier 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.

Chapter 5. Declarations

83

Storage Class Specifiers

Initialization

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.

Storage

Objects with the static storage class specifier have static storage duration. OS/390
C/C++ allocates the storage for a static variable when the program begins
running. When the program finishes running, it frees the memory.

Usage

You can use static variables when you need an object that retains its value from
one execution of a block to the next execution of that block. Using the static
storage class specifier keeps the system from reinitializing the object each time the
block where the object is defined runs.
If a local static variable is a class object with constructors and destructors, OS/390
C++ constructs the object when control passes through its definition for the first
time. If a constructor creates a local class object, OS/390 C++ calls its destructor
immediately before, or as part of, the calls of the atexit() function.

Restrictions

You cannot declare a static function at block scope.

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:
CBC3RAJ1 (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);

CBC3RAJ2 (File 2):


/************************************************************************
** This file contains the second definition of stat_var
**
************************************************************************/
#include <stdio.h>
static int stat_var = 2;

84

OS/390 V2R10.0 C/C++ Language Reference

Storage Class Specifiers


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. This variable retains its
storage throughout the program, even though test() is the only function that can
refer to stat_var.
CBC3RAAK:
/************************************************************************
** 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
stat_var
stat_var
stat_var

=
=
=
=

1
2
3
4

auto_var
auto_var
auto_var
auto_var

=
=
=
=

1
1
1
1

Related Information

v
v
v
v

Block Scope Data Declarations on page 72


File Scope Data Declarations on page 73
Function Definitions on page 178
Function Declarator on page 180

typedef
A typedef declaration lets you define your own identifiers which you can use 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.
The syntax of a typedef declaration is:
Chapter 5. Declarations

85

Storage Class Specifiers


%% typedef type_specifier identifier ;

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.
Consequently, Trees() cannot be a constructor for that class.

Examples of typedef Declarations


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, you can use typedef to define a class type (structure, union, or C++
class). For example:
typedef struct {
int scruples;
int drams;
int grains;
} WEIGHT;

You can then use the structure WEIGHT in the following declarations:
WEIGHT

chicken, cow, horse, whale;

Related Information
v
v
v
v
v
v
v
v
v
v
v

86

Characters on page 87
Floating-Point Variables on page 88
Integer Variables on page 90
Enumerations on page 91
Pointers on page 95
void Type on page 100
Arrays on page 101
Structures on page 107
Unions on page 114
Chapter 11. C++ Classes on page 277
Constructors and Destructors Overview on page 317

OS/390 V2R10.0 C/C++ Language Reference

%&

Type Specifiers

Type Specifiers
Type specifiers indicate the type of the object or function you are declaring. The
fundamental data types are:
v Characters
v Floating-Point Numbers
v Integers
v Enumerations
v Void
Under the IBM extension (using compiler option LANGLVL(EXTENDED)), the C compiler
also provides the intrinsic type:
v Fixed-point Decimal

|
|
|

From these types, you can derive:


v Pointers
v Arrays
v Structures
v Unions
v 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. You can collectively refer to
integral, floating-point, and fixed-point decimal types as arithmetic types. In C++
only, you can also derive the following:
v References
v Classes
v Pointers to Members

In C++, enumerations are not an integral type, but they can be subject to integral
promotion, as described in Integral Promotions on page 167.
You can give names to both fundamental and derived types by using the typedef
specifier.

Characters
There are three character data types: char, signed char, and unsigned char. These
three data types are not compatible. If you specify LANGLVL(ANSI), the C compiler
recognizes char, unsigned char, and signed char as distinct types. They are
always distinct types in C++.
The character data types provide enough storage to hold any member of the
character set you program uses at run time. The amount of storage that is allocated
for a char is implementation-dependent. The OS/390 C/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, described in chars on page 243.
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 that has a character type, use a char type specifier. The
char specifier has the form:
Chapter 5. Declarations

87

Type Specifiers
%%

unsigned
signed

char

%&

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 follows:
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

The following example defines the identifier end_of_string as a constant object of


type char. It has 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" };

Related Information

v
v
v
v

Character Constants on page 65


Pointers on page 95
Arrays on page 101
Assignment Expressions on page 163

Floating-Point Variables
There are three types of floating-point variables: float, double, and long double.
The amount of storage that is 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.
To declare a data object that has a floating-point type, use the float specifier.
The float specifier has the form:

88

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
%%

float
double
long double

%&

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.
Note that OS/390 C/C++ supports IEEE binary floating-point variables as well as
IBM S/390 hexadecimal floating-point variables. For details, see Floating-Point on
page 403, or the section on the FLOAT option in the OS/390 C/C++ Users Guide.

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];

Related Information

v Floating-Point Constants on page 63


v Assignment Expressions on page 163

Fixed-Point Decimal Data Types (C Only)


Use the type specifier decimal(n,p) to declare fixed-point decimal variables and to
initialize them with fixed-point decimal constants. For this type specifier, decimal is a
macro that is defined in <decimal.h>. Remember to include <decimal.h> if you use
fixed-point decimals in your program.
Fixed-point decimal types are classified as arithmetic types. The decimal(n,p) type
specifier designates a decimal number with n digits, and p decimal places. n is the
total number of digits for the integral and decimal parts combined. p is the number
of digits for the decimal part only. For example, decimal(5,2) represents a number,
such as, 123.45 where n=5 and p=2. The value for p is optional. If you leave it out,
the default value is 0.
In the type specifier, n and p have a range of allowed values according to the
following rules:
p <= n
1 <= n <= DEC_DIG
0 <= p <= DEC_PRECISION

Chapter 5. Declarations

89

Type Specifiers
Note: <decimal.h> defines DEC_DIG (the maximum number of digits n) and
DEC_PRECISION (the maximum precision p). Currently, it uses a maximum of
31 digits for both limits.
The following examples show how to declare a variable as a fixed-point decimal
data type:
decimal(10,2)
decimal(5,0)
decimal(5)
decimal(18,10)
decimal(8,2)

In
v
v
v
v

x;
y;
z;
*ptr;
arr[100];

the previous example:


x can have values between -99999999.99D and +99999999.99D.
y and z can have values between -99999D and +99999D.
ptr is a pointer to type decimal(18,10).
arr is an array of 100 elements, where each element is of type decimal(8,2).

The fixed-point decimal type specifier has the form:


%% decimal ( constant_expression

constant_expression

OS/390 C/C++ evaluates the first constant_expression as a positive integral


constant expression. The second constant_expression is optional. If you leave it
out, the default value is 0. The type specifiers, decimal(n,0) and decimal(n) are
type-compatible.

Related Information

v Fixed-Point Decimal Constants (C Only) on page 65

Integer Variables
Integer variables fall into the following categories:
v short int or short or signed short int or signed short
v signed int or int
v long int or long or signed long int or signed long
v long long int or long long or signed long long int or signed long long
v unsigned short int or unsigned short
v unsigned or unsigned int
v unsigned long int or unsigned long
v unsigned long long int or unsigned long long
Note: OS/390 C/C++ supports the long long data type for language levels other
than ANSI.
The default integer type for a bit field is unsigned. The amount of storage that is
allocated for integer data is implementation-dependent.
OS/390 C/C++ provides three sizes of integer data types. Objects that are of type
short have a length of 2 bytes of storage. Objects that are of type long have a
length of 4 bytes of storage. Objects that are of type long long have a length of 8
bytes of storage. An int data type represents the most efficient data storage size
on the system (the word-size of the machine) and receives 4 bytes of storage.

90

OS/390 V2R10.0 C/C++ Language Reference

%&

Type Specifiers
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 that has an integer data type, use an int type specifier.
The int specifier has the form:
%%

unsigned
signed

int
short
long

unsigned

%&
int
long

int

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 you can assign as 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. Chapter 13.
C++ Overloading on page 305 describes overloading and argument
matching.

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;

Related Information

v
v
v
v

Integer Constants on page 62


Decimal Constants on page 63
Octal Constants on page 63
Hexadecimal Constants on page 63

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
Chapter 5. Declarations

91

Type Specifiers
in one statement. You can also declare an enumeration type separately from the
definition of variables of that type. You refer to the identifier that is associated with
the data type (not an object) as 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.

Declaring an Enumeration Data Type

An enumeration type declaration contains the enum keyword that is followed by an


optional identifier (the enumeration tag) and a brace-enclosed list of enumerators.
Commas separate each enumerator in the enumerator list.
,
%% enum

identifier

{ ' enumerator

%&

The keyword enum, that is 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 you can convert to an integral
value.
An enumerator has the form:
%% identifier

integral_constant_expression

%&

To conserve space, you can store enumerations in spaces smaller than the storage
required by an int data type.

Enumeration Constants
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 you do not assign an explicit value, 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 that is 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

92

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
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. In the following example, the declarations of average on line
4 and of poor on line 5 cause compiler error messages:
1
2
3
4
5
6

func()
{
enum score { poor, average, good };
enum rating { below, average, above };
int poor;
}

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

*/

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

*/

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 that is followed by the name of the enumeration data type. You
must declare the enumeration data type before you can define a variable that has
that type.
The initializer for an enumeration variable contains the = symbol that is followed by
an expression.
In C, the initializer expression must evaluate to an int value. In C++, the initializer
must behave 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.

Chapter 5. Declarations

93

Type Specifiers
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;

Defining an Enumeration Type and Enumeration 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.
Variable 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 which have that
data type lets you leave the data type unnamed. For example:
enum { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday,
Saturday } weekday;

The above example defines the variable weekday, which you can assign to any of
the specified enumeration constants.

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 does not correspond with a weekday, the program prints "C'est le mauvais
jour."
CBC3RAAN:
/**
** 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");

94

OS/390 V2R10.0 C/C++ Language Reference

"

Type Specifiers

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");
}
}

Related Information

v Identifiers on page 58
v Enumeration Constants on page 92
v Constant Expressions on page 139

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:
v To access dynamic data structures such as linked lists, trees, and queues.
v To access elements of an array, or members of a structure, or members of a C++
class.
v To access an array of characters as a string.
v 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 on page 184 describes passing arguments by reference.

Declaring Pointers

The following example declares pcoat as a pointer to an object that has type long:
extern long *pcoat;

Chapter 5. Declarations

95

Type Specifiers
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. In the following example, pvolt is a
constant pointer to an object that has type short:
short * const pvolt;

The following example declares pnut as a pointer to an int object that has the
volatile qualifier:
extern int volatile *pnut;

The following example defines psoup as a volatile pointer to an object that has
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);

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 */

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 example initializes pointer amount 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. By specifying the name of the array, you can assign the address of the
first element of an array to a pointer. 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:

96

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
int section[80];
int *student = section;

The above example is equivalent to the following:


int section[80];
int *student = &section[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"
};

You can also initialize a pointer to NULL by 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.

Restrictions on C Pointers
The OS/390 C compiler supports only the pointers that are obtained in one of the
following ways:
v Directly from a malloc/calloc/realloc call
v As an address of a data type (that is, &variable)
v From constants
v Received as a parameter from another C function
v Directly from a call to an OS/390 Language Environment service that allocates
storage, such as CEEGTST
|

Any bitwise manipulation of a pointer can result in undefined behavior.

|
|
|
|

Note: For details about receiving the parameter list (argv) in C main, please refer
to the OS/390 Language Environment Programming Guide, SC28-1939,
which includes information on preparing your main routine to receive
parameters, and on C and C++ parameter passing considerations.

You cannot use pointers to reference bit fields or objects that have the register
storage class specifier.
Packed and nonpacked objects have different memory layouts. Consequently, a
pointer to a packed structure or union is incompatible with a pointer to a
corresponding nonpacked structure or union. 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, the cast operation lets you compare the two pointers, but
you must be aware that ps1 still points to a nonpacked object:

Chapter 5. Declarations

97

Type Specifiers
int main(void)
{
_Packed struct ss *ps1;
struct ss
*ps2;
.
.
.
ps1 = (_Packed struct ss *)ps2;
.
.
.
}

Using Pointers
You can use two operators when you are 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. It defines the variable p_to_x 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 to which p_to_x
points:
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;

Pointer Arithmetic
You can perform a limited number of arithmetic operations on pointers. These
operations are:
v Increment and decrement
v Addition and subtraction
v Comparison
v 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:

98

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
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 to which the pointers refer.
You can compare two pointers with the following operators: ==, !=, <, >, <;;=,
and >=. See Chapter 6. Expressions and Operators on page 133 for more
information on these operators.
You define pointer comparisons only when the pointers point to elements of the
same array. You can perform pointer comparisons that use the == and != operators
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.

Example Program Using Pointers


The following program contains pointer arrays:
CBC3RAAQ:
/********************************************************************
**
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
#define

SIZE 20
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

*/
*/

Chapter 5. Declarations

99

Type Specifiers
return(*arry);
}
return(*arry);
} /* End of find_name */

/* found it!

*/

/* return the pointer

*/

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

Related Information

v
v
v
v
v

Declarators on page 121


volatile and const Qualifiers on page 122
Initializers on page 129
Address (&) on page 145
Indirection (*) on page 145

void Type
The void data type always represents an empty set of values. The only object that
you can declare 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 that takes
no arguments is void.
You cannot declare a variable of type void, but you can explicitly convert any
expression to type void. The resulting expression can only be used as one of the
following:
v An expression statement
v The left operand of a comma expression
v The second or third operand in a conditional expression.

Example of void Type

Line 7 of the following example declares the function find_max() 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.
CBC3RAAM:
1
2
3
4
5
6
7
8
9
10

100

/**
** Example of void type
**/
#include <stdio.h>
/* declaration of function find_max */
extern void find_max(int x[ ], int j);
int main(void)
{

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

static int numbers[ ] = { 99, 54, -102, 89 };


find_max(numbers, (sizeof(numbers) / sizeof(numbers[0])));
}

return(0);

void find_max(int x[ ], int j)


{ /* begin definition of function find_max */
int i, temp = x[0];
for (i = 1; i < j; i++)
{
if (x[i] > temp)
temp = x[i];
}
printf("max number = %d\n", temp);
} /* end definition of function find_max

*/

Arrays
An array is an ordered group of data objects. Refer to each object as 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.

Declaring Arrays
The array declarator contains an identifier that is followed by an optional subscript
declarator. An identifier that is preceded by an * (asterisk) is an array of pointers.
A subscript declarator has the form:

%% [

constant_expression

] '

%&

constant_expression ]

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. Note that the [
and ] characters can be represented by the trigraphs ??( and ??) respectively.
The following example defines a one-dimensional array that contains four elements
that have 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];

Chapter 5. Declarations

101

Type Specifiers
OS/390 C/C++ stores multidimensional arrays in row-major order. When you are
referring to elements in order of increasing storage location, the last subscript varies
the fastest. For example, consider the following elements of array roster:
roster[0][0]
roster[0][1]
roster[1][0]
roster[1][1]
roster[2][0]
roster[2][1]

OS/390 C/C++ stores the elements of roster 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 the
following instances:
v Array definitions that contain initializations
v extern declarations
v 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, OS/390 C/C++ compares the initializer 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:
v In arrays that are declared at file scope
v In the argument list of a function declaration
In function declarations and declarations with the extern specifier, the only
dimension you can leave empty is the first one. You must specify the sizes of
additional dimensions.
In extended modes, you can also use unsubscripted array names in the following
contexts:
v In union members
v As the last member of a structure
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
you use an array as an operand of the sizeof or the address (&) operator.

Initializing Arrays

The initializer for an array contains the = symbol that is followed by a


comma-separated list of constant expressions that are 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.

102

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
Note: Array initializations can be either fully braced (with braces around each
dimension) or unbraced (with only one set of braces that enclose the entire
set of initializers). Avoid placing braces around some dimensions and not
around others.
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]

number[1]

number[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]

number1[1]

number1[2]

Instead of an expression in the subscript declarator that defines 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]

item[1]

item[2]

item[3]

item[4]

You can initialize a one-dimensional character array by specifying:


v A brace-enclosed, comma-separated, list of constants, each of which can be
contained in a character
v A string constant. (Braces that surround 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 you do not specify the array dimensions.
The following definitions show character array initializations:
static char name1[ ] = { 'J', 'a', 'n' };
static char name2[ ] = { "Jan" };
static char name3[4] = "Jan";
Chapter 5. Declarations

103

Type Specifiers
These definitions create the following elements:
Element

Value

Element

Value

Element

Value

name1[0]
name1[1]
name1[2]

J
a
n

name2[0]
name2[1]
name2[2]
name2[3]

J
a
n
\0

name3[0]
name3[1]
name3[2]
name3[3]

J
a
n
\0

Note that the following definition would result in the null character being lost:
static char name[3]="Jan";

In C, the compiler accepts name[3] with no warning or error messages. In C++, the
compiler generates an error message that states the character array must be at
least 4 characters in size to accept the string literal. To initialize this array in C++,
use character-by-character initialization, for example:
static char name[3]={'J','a','n'};

You can initialize a multidimensional array by the following methods:


v 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
};

v 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 }
};

v Using nested braces to initialize dimensions and elements in a dimension


selectively.
The following definition explicitly initializes six elements in a 12-element array:
static int matrix[3][4] =
{
{1, 2},
{3, 4},
{5, 6}
};

104

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
The initial values of matrix are:
Element

Value

Element

Value

matrix[0][0]
matrix[0][1]
matrix[0][2]
matrix[0][3]
matrix[1][0]
matrix[1][1]

1
2
0
0
3
4

matrix[1][2]
matrix[1][3]
matrix[2][0]
matrix[2][1]
matrix[2][2]
matrix[2][3]

0
0
5
6
0
0

You cannot have more initializers than the number of elements in the array.
C++ Notes:
1. In C++, you can use a zero-sized array in a class definition, but it must be
non-static.
2. In a class definition, the zero-sized array must be the last non-static data
member. You can use members such as functions, static data members, and
typedefs after the zero-sized array.
3. You cannot use a class that contains a zero-sized array as a base class.

Example Programs Using Arrays

The following program defines a floating-point array that is called prices.


The first for statement prints the element values of prices. The second for
statement adds five percent to the value of each element of prices. of total.
CBC3RAAO:
/**
** 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);

Chapter 5. Declarations

105

Type Specifiers
This program produces the following output:
price
price
price
price
price

=
=
=
=
=

$1.41
$1.50
$3.75
$5.00
$0.86

total
total
total
total
total

=
=
=
=
=

$1.48
$1.57
$3.94
$5.25
$0.90

The following program defines the multidimensional array salary_tbl. A for loop
prints the values of salary_tbl.
CBC3RAAP:
/**
** 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]
salary_tbl[0]
salary_tbl[0]
salary_tbl[0]
salary_tbl[0]
salary_tbl[1]
salary_tbl[1]
salary_tbl[1]
salary_tbl[1]
salary_tbl[1]
salary_tbl[2]
salary_tbl[2]
salary_tbl[2]
salary_tbl[2]
salary_tbl[2]

106

[0]
[1]
[2]
[3]
[4]
[0]
[1]
[2]
[3]
[4]
[0]
[1]
[2]
[3]
[4]

=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

500
550
600
650
700
600
670
740
810
880
740
840
940
1040
1140

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers

Related Information

v
v
v
v
v
v

Pointers on page 95
Array Subscript [ ] (Array Element Specification) on page 141
String Literals on page 66
Declarators on page 121
Initializers on page 129
Chapter 7. Implicit Type Conversions on page 167

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 the following variables:
int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;

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
2
3
4
5
6
7
8
9
10

struct address {

int street_no;
char *street_name;
char *city;
char *prov;
char *postal_code;
};
struct address perm_address;
struct address temp_address;
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 assign a pointer to the string "Ontario" to the
pointer prov that is in the structure perm_address:
perm_address.prov = "Ontario";
p_perm_address -> prov = "Ontario";

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.

Chapter 5. Declarations

107

Type Specifiers
If you need direct control of byte mapping, use pointers. Dot Operator (.) on
page 142 and Arrow Operator (>) on page 142 describe structure member
references.
You cannot declare a structure with members of incomplete types. See Incomplete
Types on page 121 for more information.

Declaring a Structure
A structure type declaration describes the members that are part of the structure. It
contains the struct keyword that is followed by an optional identifier (the structure
tag), and a brace-enclosed list of members.
A structure declaration has the form:
%%

_Packed

struct

identifier

%&
{ '

identifier

member ;

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 you
can stored in the structure.
A structure member definition has the form:
,
%% type_specifier '

declarator
.declarator

constant_expression

%&

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.Declaring and Using Bit
Fields in Structures on page 110 describes bit fields.
You can redefine identifiers that are used as structure or member names 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. You can, however, 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. You can,
however, declare a structure type that contains a pointer to itself as a member.

Defining a Structure Variable


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.

108

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
C++ Note: The keyword struct is optional in C++.
You can declare structures that have any storage class. Most compilers, however,
treat structures that are declared with the register storage class specifier as
automatic structures.

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. However, you need to initialize all members in the structure prior to the
member of interest. For example, if you are interested in initializing the fifth member
of a structure, you must initialize the first four members, as well. You do not have to
initialize the sixth and subsequent members. You cannot initialize unnamed bit
fields.
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

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" };

Chapter 5. Declarations

109

Type Specifiers
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 on page 74for details on the
initialization of different storage classes.

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 you can define a
member or a structure variable 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.

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.

110

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
Bit fields with a length of 0 must be unnamed. You cannot reference or initialize
unnamed bit fields. 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. A _Packed structure, a bit field of length 0, causes the next field
to align on the next byte boundary.
The maximum bit-field length is implementation dependent.
For portability, do not use bit fields greater than 32 bits in size.
The following restrictions apply to bit fields. You cannot:
v Define an array of bit fields
v Take the address of a bit field
v Have a pointer to a bit field
v 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.
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 an out-of-range value to a bit field,
OS/390 C/C++ preserves the low-order bit pattern and assigns the
appropriate bits.
If a series of bit fields does not add up to the size of an int, padding can take
place. OS/390 C/C++ determines the amount of padding by the alignment
characteristics of the structure members. In some instances, bit fields can cross
word boundaries.
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 ;

Chapter 5. Declarations

111

Type Specifiers
The structure kitchen contains eight members that total 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 a value that is out of its range to a bit field, OS/390 C/C++
preserves the bit pattern and assigns the appropriate bits. The following expression
sets the toaster field of the kitchen structure to 0 because it assigns only the least
significant bit to the toaster field:
kitchen.toaster = 2;

Declaring a Packed Structure

To qualify a C structure as packed, use _Packed qualifier on the structure


declaration.
C++ Note: C++ does not support the _Packed qualifier. To change the alignment of
C++ structures, use the #pragma pack directive (supported by both C
and C++). Refer to pack on page 266 for information on this directive.
Packed and nonpacked structures cannot be assigned to each other, regardless of
their type.

Example Program Using Structures


The following program finds the sum of the integer numbers in a linked list:

112

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
CBC3RAAS:
/**
** 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 example assigns the following values to the record type variables name1, name2,
and name3:
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. OS/390 C/C++


initializes it 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 following statement advances the pointer to the next object in the list:
recd_pointer = recd_pointer->next_num;
Chapter 5. Declarations

113

Type Specifiers
Alignment of Structures: Normal structure alignment aligns the structure
members on their natural boundaries and ends the structure on its natural
boundary. The alignment of the structure is that of its strictest member. The
compiler performs normal alignment when your program meets one of the following
conditions:
v It does not specify the #pragma pack directive
v It specifies #pragma pack() before the structure declaration
v It specifies #pragma pack(full) before the structure declaration
To change the alignment back to what it was before the last #pragma pack, use the
reset option.
Consider if, by default, the compiler packs data types along boundaries smaller than
those specified by #pragma pack. The compiler still aligns them along the smaller
boundaries. For example, the compiler always aligns type char along a 1-byte
boundary, regardless of the value of #pragma pack.
Consider when more than one #pragma pack directive appears in a structure defined
in an inlined function. In that case, the #pragma pack directive that is in effect at the
beginning of the structure takes precedence.
For information on calling C packed structures from C++, see the OS/390 C/C++
Programming Guide. For information on packing C structures, see _Packed
Qualifier (C Only) on page 124. For information on alignment of unions, see
Alignment of Unions on page 119. For information how to use the #pragma pack
directive to change alignment, see pack on page 266.
Alignment of Nested Structures: A nested structure has the alignment that
precedes its declaration, not the alignment of the structure in which it is contained.
#pragma pack ()
struct nested {
int x;
char y;
int z;
};

// full alignment

#pragma pack(1)
struct packedcxx{
char
a;
short b;
struct nested s1;
};

// 1-byte alignment

// full alignment

Related Information

v
v
v
v
v

Declarators on page 121


Initializers on page 129
Incomplete Types on page 121
Dot Operator (.) on page 142
Arrow Operator (>) on page 142

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. OS/390 C/C++ overlays the
members 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).

114

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
C++ Notes:
1. In C++, a union can have member functions, including constructors and
destructors, but not virtual member functions. You cannot use a union as a base
class nor derive it from a base class.
2. A C++ union member cannot be a class object that has a constructor,
destructor, or overloaded copy assignment operator. In C++, you cannot declare
a member of a union with the keyword static.

Declaring a Union

A union type declaration contains the union keyword followed by an identifier


(optional) and a brace-enclosed list of members.
A union declaration has the form:

%%

qualifier

union

{ '

identifier

member ;

%&

The identifier is a tag you give to the union that is specified by the member list. If
you specify a tag, you can make any subsequent declaration of the union (in the
same scope) 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 you
can store in the union.
A union member definition has the form:
,
%% type_specifier '

declarator
.declarator

%&

constant_expression

You can reference one of the possible union members the same way as you
reference a member of a structure.
For example, the following code assigns '\n' to the first element in the character
array birthday, a member of the union people:
union {
char birthday[9];
int age;
float weight;
} people;
people.birthday[0] = '\n';

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 that is assigned to people.birthday in the
first line:
Chapter 5. Declarations

115

Type Specifiers
1
2
3

people.birthday = "03/06/56";
people.age = 38;
printf("%s\n", people.birthday);

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.
Type Specifier: The type specifier contains the keyword union that is followed by
the name of the union type. You must declare the union data type before you can
define a union that has 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.
Declarator: The declarator is an identifier, possibly with the volatile or const
qualifier.
Initializer: 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"};

Defining a Union Type and a Union Variable


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.

Defining Packed Unions

To qualify a C union as packed, use _Packed.


C++ Note: C++ does not support the _Packed qualifier. To change the alignment of
C++ unions, use the #pragma pack directive (which both C and C++
support). For more information on this directive, see pack on
page 266.
Packed and nonpacked unions cannot be assigned to each other, regardless of
their type.
The #pragma pack does not affect the memory layout of the union members. Each
member starts at offset zero. The #pragma pack directive does affect the total
alignment restriction of the whole union.
In the following example, each of the elements in the nonpacked n_array is of type
union uu:
union uu
short
struct
char
char
char
} b;
};

116

a;
{
x;
y;
z;

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
union uu
n_array[2];
/* _Packed union is not supported for C++
_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.) 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.
The following equivalent C++ example uses the #pragma pack directive instead of
the _Packed qualifier:
union uu
short
struct
char
char
char
} b;
};

{
{
x;
y;
z;

a;

union uu
n_array[2];
#pragma pack(pack)
union uu p_array[2];
#pragma pack(reset)

Anonymous Unions in C
You can declare unions without declarators if they are members of another structure
or union. Refer to unions without declarators as anonymous unions. C supports
anonymous unions only when you use the LANGLVL(COMMONC) compiler option.
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;
Chapter 5. Declarations

117

Type Specifiers
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, you can access the members 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 you declare a union 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;
};

You cannot use the variables b and c from this union at file scope, and so the
following statements generate errors:
b = 5;
c = 2.5;

Anonymous Unions in C++


A C++ anonymous union is a union without a class name. A declarator cannot
follow an anonymous union. 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 that contains 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. You must declare
a global anonymous union with the keyword static.

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.

118

OS/390 V2R10.0 C/C++ Language Reference

Type Specifiers
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 that is named records. Each
element of records contains three members: the integer id_num, the integer
type_of_input, and the union variable input. The variable 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';

Alignment of Unions: You can perform packing in a union. Each member starts
at offset zero, and the entire union spans as many bytes as its largest element. The
#pragma pack affects the total alignment restriction of the whole union. Consider the
following example:
Without Packing:
union uu
short
struct
char
char
char
} b;
};
union uu

{
{
x;
y;
z;

a;

array[2];

First, consider the non-packed array. Each of its elements is of type union uu.
Since it is non-packed, every element has an alignment restriction of 2 bytes. The
largest alignment requirement among the union members is that of short a. There
is one byte of padding at the end of each element to enforce this requirement.

Chapter 5. Declarations

119

Type Specifiers
array[0] array[1]

x y z
x y z

0
1
2
3
4
5
6
7
8

With #pragma pack(packed):


#pragma pack(packed)
union uu
short
struct
char
char
char
} b;
};

a;
{
x;
y;
z;

union uu

p1_array[2];

Now consider the packed array p1_array. Since the example specifies #pragma
pack(packed), the alignment restriction of every element is the byte boundary.
Therefore, each element has a length of only 3 bytes, as opposed to the 4 bytes of
the previous case.
p_array[0] p_array[1]

x y z x y z

0
1
2
3
4
5
6

For information on calling unions from C++, see the OS/390 C/C++ Programming
Guide. For information on structure alignment, see Alignment of Structures on
page 114 and Alignment of