C CPP Reference Manual
C CPP Reference Manual
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.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
53
53
53
54
55
56
56
58
58
58
59
59
59
60
60
61
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Contents
62
63
65
65
66
68
133
133
135
135
136
136
136
137
137
138
138
139
140
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
167
167
167
168
168
168
168
169
169
169
170
170
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
vi
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
. .
. .
. .
. .
. .
. .
. .
. .
. .
viii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
277
277
277
278
278
279
280
282
282
282
283
284
285
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
317
317
318
318
318
319
320
320
322
324
325
325
326
326
327
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
357
357
358
359
359
359
360
362
362
363
364
365
365
365
366
366
367
368
368
369
370
Contents
xi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
xii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
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
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++.
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
Books
Installing
Coding programs
v
v
v
v
v
v
v
v
v
v
v
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
v
v
v
v
Books
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
|
|
|
Quick reference
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
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.
|
|
|
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.
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.
%&
%&
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
%&
%% 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
The comment type must be entered only as one of the following: compiler,
date, timestamp, copyright, or user.
A character string must follow the comma. The character string must be
enclosed in double quotation marks.
10
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 C/C++ has made the following performance and usability enhancements for
this release:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GOFF
|
|
|
|
|
IPA Level 2
|
|
|
|
|
COMPACT
13
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.)
|
|
|
|
14
|
|
|
|
|
|
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 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
16
|
|
- const_cast
Explicit specifier
Mutable specifier
Namespace
Run-Time Type Identification (RTTI)
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
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.
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.
20
C/C++
Language
Specific
Library
COBOL
Language
Specific
Library
PL/I
Language
Specific
Library
FORTRAN
Language
Specific
Library
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/
21
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.
22
ar
BPXBATCH
c89
dbx
gencat
iconv
lex
localedef
make
yacc
mkcatdefs
runcat
dspcat
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/
23
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
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).
25
v
v
v
v
26
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++.
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
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.
|
|
|
|
|
You can redirect the standard streams stdin, stderr, and stdout from the command
line or when calling programs using the system() function.
OS/390 C/C++ provides message text in either American English or Japanese. You can
dynamically switch between the two languages.
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.
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 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 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.
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
|
|
|
|
|
Feature
Description
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.
29
30
31
32
33
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
Directives
Declarations
Definitions
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.
/* Preprocessor directive
*/
double x = 45.0;
*/
double y = NUM;
34
C Source Programs
int main(void)
{
/* Function definition
for main function
*/
double z;
double w;
*/
z = cos(x);
*/
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.
1
2
3
/* 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;
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
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.
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
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;
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;
printf("%d\n", i);
/* Prints 2 */
}
printf("%d\n", i);
/* Prints 1 */
return 0;
}
Related Information
v
v
v
v
v
v
v
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
Program Linkage
Internal
Identical identifiers within a single source file refer to the same data
object or function.
External
No linkage
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.
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
Automatic storage
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
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;
/*
*/
*/
*/
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.
argv[0]
41
Command-Line Arguments
argv[1 to n]
argc
Returns 1
argv[0]
Is a null pointer
argc
Returns 1
argv[0]
Under IMS
Under CICS
argv[0]
argv[1 to n]
argv
argv[0]
argv[1 to n]
argv[0]
argv[1 to n]
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')
42
Command-Line Arguments
Related Information
v
v
v
v
v
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.
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.
44
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.
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);
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
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.
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.
48
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.
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 (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.
50
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.
51
Linkage Specifications
52
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.
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>
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
Character Set
??=
??(
??)
??<
??>
??/
??
??!
??-
#
[
]
{
}
\
|
|
number sign
left bracket
right bracket
left brace
right brace
backslash
caret
vertical bar
tilde
Example
some_array??(i??) = n;
Represents:
some_array[i] = n;
Digraph Characters
|
|
|
%: or %%
<:
:>
<%
%>
%:%: or
%%%%
#
[
]
{
}
##
number sign
left bracket
right bracket
left brace
right brace
preprocessor macro concatenation operator
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 '%>'
}
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
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;
}
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
#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 */
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
_
$
%&
58
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.
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
_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
For more information on the #pragma map directive, see map on page 259.
60
Identifiers
CBC3244 ./sum.c:2
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
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 Type
unsuffixed decimal
unsuffixed octal
unsuffixed hexadecimal
suffixed by u or U
suffixed by l or L
suffixed by ll or LL
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
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
%%
0x
0X
'
digit_0_to_f
digit_0_to_F
%&
Octal Constants
An octal constant begins with the digit 0 and contains any of the digits 0 through 7.
%% 0 ' digit_0_to_7
%&
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
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
%&
Constants
%%
'
digit_0_to_9
D
d
' digit_0_to_9
' digit_0_to_9
'
%&
digit_0_to_9
' digit_0_to_9
(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.
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
"
66
%&
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"
*/
*/
*/
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";
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 ;
}
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
%&
68
Constants
The escape sequences and the characters they represent are:
Escape Sequence
Character Represented
\a
\b
Backspace
\f
\n
New-line
\r
Carriage return
\t
Horizontal tab
\v
Vertical tab
\'
\"
\?
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;
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;
}
69
Constants
70
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
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:
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
double pi = 3.14159265;
struct payroll;
struct payroll {
char *name;
float salary;
} employee;
72
auto
register
static
extern
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
Chapter 5. Declarations
73
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
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.
74
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
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;
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
return(0);
When you run the program, interaction with the program could produce:
Output
Enter letters:
Input
zyfab
Output
Related Information
v
v
v
v
77
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
78
// 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();
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();
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
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.
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.
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
/**************************************************************
** 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
*/
return(0);
/* end main
*/
/**************************************************************
** 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 */
float total;
When you run this program and interaction with it, it could produce the following:
Output
Input
99.95
Output
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
return(0);
void sort(void)
{
int gap, i, j, temp;
When you run this program, interacting with it could produce the following:
Output
Enter letters:
Input
zyfab
Output
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
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;
Related Information
v
v
v
v
Chapter 5. Declarations
83
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
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);
84
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);
}
=
=
=
=
1
2
3
4
auto_var
auto_var
auto_var
auto_var
=
=
=
=
1
1
1
1
Related Information
v
v
v
v
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
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;
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
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
%&
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
|
|
|
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.
The following example defines the unsigned char variable switches as having the
initial value 3:
unsigned char switches = 3;
Related Information
v
v
v
v
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
Type Specifiers
%%
float
double
long double
%&
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 defines the array table with 20 elements of type double:
double table[20];
Related Information
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];
constant_expression
Related Information
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
%&
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.
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
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.
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
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
*/
*/
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;
C++ also lets you put the storage class immediately before the declarator. For
example:
enum score { poor=1, average, good } register 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.
94
"
Type Specifiers
scanf("%d", &num);
weekday=num;
french(weekday);
return(0);
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;
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
Type Specifiers
int section[80];
int *student = section;
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";
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
|
|
|
|
|
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
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.
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!
*/
*/
Input
Mark
Output
OR:
Output
Input
Deborah
Output
Related Information
v
v
v
v
v
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.
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)
{
Type Specifiers
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
return(0);
*/
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]
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
102
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 };
Value
number[0]
number[1]
number[2]
Value
number1[0]
number1[1]
number1[2]
Value
item[0]
item[1]
item[2]
item[3]
item[4]
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'};
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 }
};
104
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.
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);
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
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.
108
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"};
Value
perm_address.street_no
perm_address.street_name
perm_address.city
perm_address.prov
perm_address.postal_code
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
temp_address.city
temp_address.prov
temp_address.postal_code
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.
110
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)
count
ac
4 bits
(unnamed field)
4 bits
clock
1 bit
(padding 23 bits)
flag
1 bit
(padding 31 bits)
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;
112
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
name2.number
203
name2.next_num
name3.number
488
name3.next_num
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
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
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
%%
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);
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"};
116
a;
{
x;
y;
z;
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;
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;
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
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 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
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