0% found this document useful (0 votes)
57 views335 pages

AS400 C++ Users Guide

AS400 C++ Language Reference

Uploaded by

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

AS400 C++ Users Guide

AS400 C++ Language Reference

Uploaded by

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

Note!

Before using this information and the product it supports, be sure to read the general information under
“Notices” on page xiii.

First Edition (September 1995)

This edition applies to Version 3, Release 6, Modification Level 0, of IBM VisualAge C++ for OS/400 (Program 5716-CX4) and
to all subsequent releases and modifications until otherwise indicated in new editions. Make sure you are using the correct
edition for the level of the product. Consult the latest edition of the applicable IBM system bibliography for current information
on this product.

Order publications through your IBM representative or the IBM branch office serving your locality. Publications are not stocked
at the address given below.

A form for readers’ comments is provided at the back of this publication. If the form has been removed, address your comments
to:

IBM Canada Ltd. Laboratory


Information Development
2G/345/1150/TOR
1150 Eglinton Avenue East
North York, Ontario, Canada. M3C 1H7

You can also send your comments by facsimile (attention: RCF Coordinator), or you can send your comments electronically to
IBM. See “Communicating Your Comments to IBM” for a description of the methods. This page immediately precedes the
Readers’ Comment Form at the back of this publication.

When you send information to IBM, you grant IBM a nonexclusive right to use or distribute the information in any way it
believes appropriate without incurring any obligation to you.

 Copyright International Business Machines Corporation 1995. All rights reserved.


Note to U.S. Government Users — Documentation related to restricted rights — Use, duplication or disclosure is subject to
restrictions set forth in GSA ADP Schedule Contract with IBM Corp.
Contents
Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Programming Interface Information . . . . . . . . . . . . . . . . . . . . . . . . xiii
Trademarks and Service Marks . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv

About this Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv


Who Should Use This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
How to Use this Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
How to Read the Syntax Diagrams . . . . . . . . . . . . . . . . . . . . . . . . xvi
Syntax for Commands, Preprocessor Directives, and Statements . . . . . . . xvi
Syntax for Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Highlighting Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii
Icons Used in This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
How to Get Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xix
Getting Help Inside VisualAge C++ for OS/400 . . . . . . . . . . . . . . . . . xx
Getting Help from the Command Line . . . . . . . . . . . . . . . . . . . . . xxi
BookManager Books . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

Part 1. Developing OS/400 Applications with WorkFrame . . . 1

Chapter 1. Introducing WorkFrame . . . . . . . . . . . . . . . . . . . . . . . 3


Overview of the WorkFrame Development Environment . . . . . . . . . . . . . . 3
Getting Started With WorkFrame . . . . . . . . . . . . . . . . . . . . . . . . . . 4
WorkFrame Terms and Concepts You Need to Know . . . . . . . . . . . . . 5
Customizing WorkFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Getting Help for WorkFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Using Contextual Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Using "How Do I..." Information . . . . . . . . . . . . . . . . . . . . . . . . 7

Chapter 2. Using WorkFrame with VisualAge C++ for OS/400 . . . . . . . . 9


Choosing the Appropriate Development Tools . . . . . . . . . . . . . . . . . . . 9
Correspondence Between OS/2 and OS/400 Objects . . . . . . . . . . . . . . 10
WorkFrame Actions are Context-Sensitive . . . . . . . . . . . . . . . . . . . . 10
WorkFrame Actions for OS/400 Projects . . . . . . . . . . . . . . . . . . . . . . 12
Developing Client/Server Applications With WorkFrame . . . . . . . . . . . . . 14

Chapter 3. Creating OS/400 C++ Applications with WorkFrame . . . . . . . 17


Setting Up a Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Creating and Naming a Project . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Designating a Project Target . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Locating Project Parts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

 Copyright IBM Corp. 1995 iii


Customizing the Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Creating and Editing Source Files . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Introducing the VisualAge Editor . . . . . . . . . . . . . . . . . . . . . . . . . 21
Invoking an Editor from within WorkFrame . . . . . . . . . . . . . . . . . . . 21
Compiling Source Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Setting Compiler Options in Build Smarts . . . . . . . . . . . . . . . . . . . . 22
Setting Compiler Options in the Compiler Options Notebook . . . . . . . . . 22
Invoking the Compiler from within WorkFrame . . . . . . . . . . . . . . . . . 23
Creating Programs and Service Programs . . . . . . . . . . . . . . . . . . . . . . 24
Setting Binder Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Invoking the Binder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Browsing Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Restrictions When Browsing OS/400 Applications . . . . . . . . . . . . . . . 26
Invoking the VisualAge Browser . . . . . . . . . . . . . . . . . . . . . . . . . 26
Debugging an OS/400 Application . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Preparing for Debugging with the VisualAge C++ for OS/400 Debugger . . . 27
Invoking the Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Using the MakeMake Utility for OS/400 Projects . . . . . . . . . . . . . . . . . 29
Creating a Project With Multiple Inheritance . . . . . . . . . . . . . . . . . . . . 30
Inheriting from OS/2 and OS/400 Project Templates . . . . . . . . . . . . . . 30
Adding an Action to a Project's Tools setup . . . . . . . . . . . . . . . . . . . . 31
Adding a Connect Action to the Run Action Class . . . . . . . . . . . . . . . 31

Part 2. Compiling Your Program . . . . . . . . . . . . . . . . . . . . . 35

Chapter 4. Starting the Compiler . . . . . . . . . . . . . . . . . . . . . . . . . 37


Compiling across Operating Systems . . . . . . . . . . . . . . . . . . . . . . . . 37
Communication between OS/2 Workstation and AS/400 . . . . . . . . . . . . 38
Creating and Transferring Intermediate Code Files . . . . . . . . . . . . . . . 39
Compiling Source Code into Module Objects . . . . . . . . . . . . . . . . . . 39
Establishing an AS/400 Connection Before Compiling and Binding . . . . . . . 40
Setting up Host Server Sessions on the AS/400 . . . . . . . . . . . . . . . . . 41
Using the CTTCONN Command to Connect to an AS/400 . . . . . . . . . . . 41
Identifying an AS/400 System Through its Partner LU Name or Alias . . . . 43
Specifying a User-Defined AS/400 Connection Name . . . . . . . . . . . . . 43
Establishing Multiple Connections Between an OS/2 Workstation and an
AS/400 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Querying Existing Connections through CTTQCONN . . . . . . . . . . . . . 44
Issuing AS/400 CL Commands from the OS/2 Workstation . . . . . . . . . . 45
Ending an AS/400 Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Recovering from an OS/2 Workstation Reboot . . . . . . . . . . . . . . . . . 48
Invoking the Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Compiling from within WorkFrame . . . . . . . . . . . . . . . . . . . . . . . 49

iv IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiling from a Make File . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Compiling from the OS/2 Command Line . . . . . . . . . . . . . . . . . . . . 50
Compiling Files Without a File Extension . . . . . . . . . . . . . . . . . . . . 51
Compiling Multiple Source Files into Modules . . . . . . . . . . . . . . . . . 51
Compiling C Source Files With the C++ Compiler . . . . . . . . . . . . . . . 52
Invoking the Compiler Using A Response File . . . . . . . . . . . . . . . . . 52
Determining Compiler Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Creating a Program Using iccas Defaults . . . . . . . . . . . . . . . . . . . . . 53
Creating a Program Using Specific Compiler Options . . . . . . . . . . . . . 54
Compiling in Connected Mode . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Compiling in Disconnected Mode . . . . . . . . . . . . . . . . . . . . . . . . . 54
Creating an Intermediate Code File Only . . . . . . . . . . . . . . . . . . . . . 55
Working With Multiple Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Using the INCLUDE Environment Variable . . . . . . . . . . . . . . . . . . . 57
Using the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 Environment
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Chapter 5. Controlling Compiler Input . . . . . . . . . . . . . . . . . . . . . 59


File Naming Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Using Wild Cards in File Names . . . . . . . . . . . . . . . . . . . . . . . . . 60
Reserved Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Input File Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
OS/2 Environment Variables for Compiling . . . . . . . . . . . . . . . . . . . . . 62
Setting Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Source File Names in ICCAS . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Controlling #include Search Paths . . . . . . . . . . . . . . . . . . . . . . . . . 66
#include Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
#include File Name Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Ways to Control the #include Search Paths . . . . . . . . . . . . . . . . . . . 67
#include Search Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Search Order for Externally Described Files . . . . . . . . . . . . . . . . . . . 68
Accumulation of Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Setting the Source Code Language Level . . . . . . . . . . . . . . . . . . . . . . 70
Choosing a Language Level . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Compile-Time Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Chapter 6. Controlling Compiler Output . . . . . . . . . . . . . . . . . . . . 73


Output File Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Intermediate Code Files and Module Objects . . . . . . . . . . . . . . . . . . 74
Program and Service Program Objects . . . . . . . . . . . . . . . . . . . . . . 76
Compiler Listings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Temporary Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Messages and Return Codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

Contents v
Precompiled Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Location and Time Stamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Search Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
When a Precompiled Header File is Not Used . . . . . . . . . . . . . . . . . . 80
Creating and Maintaining Precompiled Header Files Automatically . . . . . . 80
Restrictions When Using Precompiled Header Files . . . . . . . . . . . . . . . 81
Inlining User Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Compiling Applications to Run in an AS/400 V3R1 IMPI Environment . . . . . 85
Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Run-Time Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Copying V3R1 System Header Files to Your OS/2 Workstation . . . . . . . . 87

Chapter 7. Setting Compiler Options . . . . . . . . . . . . . . . . . . . . . . . 89


Specifying Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Using Parameters with Compiler Options . . . . . . . . . . . . . . . . . . . . 91
Scope of Compiler Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Options Having a Special Scope . . . . . . . . . . . . . . . . . . . . . . . . . 93
Related Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Conflicting Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Compiler Option Classification . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Options Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Output File Management Options . . . . . . . . . . . . . . . . . . . . . . . . . . 97
/ASd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
/ASl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
/ASr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
/Fb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
/Fc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
/Fi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
/Fl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
/Fo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
/Ft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
/Fw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
#include File Search Options . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
/I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
/Xc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
/Xi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
Listing File Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
/L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
/La . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
/Lb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
/Le . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
/Lf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
/Li . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

vi IBM VisualAge C++ for OS/400 C++ User’s Guide


/Lj . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
/Lp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
/Ls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
/Lt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
/Lu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
/Lx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
/Ly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
Debugging and Diagnostic Information Options . . . . . . . . . . . . . . . . . 108
/N . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
/Ti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
/W . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
/Wgrp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Source Code Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
/S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
/Si . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
/Sn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
/Sp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
/Su . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
Preprocessor Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
/D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
/P . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
/Pc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
/Pd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
/Pe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
/U . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Code Generation Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
/ASi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
/ASp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
/Oi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
Other Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
/? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
/ASa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
/AScp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
/ASn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
/ASt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
/ASv3r1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
/B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
/C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
/J . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
/Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
/Tl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
/V . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124

Contents vii
Part 3. Binding and Running Your Program . . . . . . . . . . . . 125

Chapter 8. Creating an OS/400 Program . . . . . . . . . . . . . . . . . . . 127


Binding Modules into Programs . . . . . . . . . . . . . . . . . . . . . . . . . . 127
Program and User Entry Procedures . . . . . . . . . . . . . . . . . . . . . . 127
Internal Structure of a Program Object . . . . . . . . . . . . . . . . . . . . . 128
Static Procedure Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Service Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Binding Directories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Invoking CL Commands from OS/2 through CTTHCMD . . . . . . . . . . . . 129
Invoking the Binder to Create a Program . . . . . . . . . . . . . . . . . . . . . 130
Parameters for the CRTPGM Command . . . . . . . . . . . . . . . . . . . . 130
Before Issuing the CRTPGM Command . . . . . . . . . . . . . . . . . . . . 131
How to Issue the CRTPGM Command . . . . . . . . . . . . . . . . . . . . . 131
How the Binder Resolves Imports . . . . . . . . . . . . . . . . . . . . . . . 134
Using a Binder Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
Changing a Module or a Program Object . . . . . . . . . . . . . . . . . . . . . 135
Updating a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Changing the Optimization Level . . . . . . . . . . . . . . . . . . . . . . . . 137
Removing Observability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Reducing an Object's Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

Chapter 9. Creating a Service Program . . . . . . . . . . . . . . . . . . . . 141


Overview of the Service-Program Concept . . . . . . . . . . . . . . . . . . . . 141
Differences between Programs and Service Programs . . . . . . . . . . . . . 141
Binding a Service Program to a Program . . . . . . . . . . . . . . . . . . . . 141
Invoking the Binder to Create a Service Program . . . . . . . . . . . . . . . . . 142
Parameters for the CRTSRVPGM Command . . . . . . . . . . . . . . . . . 142
How to Issue the CRTSRVPGM Command . . . . . . . . . . . . . . . . . . 143
Updating or Changing a Service Program . . . . . . . . . . . . . . . . . . . 144
Related CL commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Example of How to Create a Service Program . . . . . . . . . . . . . . . . . . 145
Program Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Creating the Service Program . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Binding the Service Program to a Program . . . . . . . . . . . . . . . . . . 148

Chapter 10. Working With Exports From Service Programs . . . . . . . . 151


Determining Exports from Service Programs . . . . . . . . . . . . . . . . . . . 151
Displaying Export Symbols With the Display Module Command . . . . . . 152
Creating a Binder-Language Source File . . . . . . . . . . . . . . . . . . . . . 153
Creating Binder Language Using SEU . . . . . . . . . . . . . . . . . . . . . 153
Creating Binder Language Using the RTVBNDSRC Command . . . . . . . 154
Updating a Service Program Export List . . . . . . . . . . . . . . . . . . . . 156
viii IBM VisualAge C++ for OS/400 C++ User’s Guide
Using the Demangling Functions . . . . . . . . . . . . . . . . . . . . . . . . 157
Handling Unresolved Import Requests During Program Creation . . . . . . . . 158
Example of Creating a Service Program Using Binder Language . . . . . . . . 158
Example of Creating a Program with Circular References . . . . . . . . . . . . 159
Handling Unresolved Import Requests with *UNRSLVREF . . . . . . . . . 163
Handling Unresolved Import Requests by Changing Program-Creation Order 164
Example of Binding a Program to a Non-existing Service Program . . . . . . . 165
Example of Updating a Service-Program Export List . . . . . . . . . . . . . . . 166

Chapter 11. Creating a Make File . . . . . . . . . . . . . . . . . . . . . . . 171


Creating Your Own Make File . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Format of a Make File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Conditions and Restrictions of Make Files . . . . . . . . . . . . . . . . . . . . 173
Mounting a Host Path as a Network Drive on OS/2 . . . . . . . . . . . . . . 173
Restrictions When Comparing Time Stamps . . . . . . . . . . . . . . . . . . 174
Synchronizing System Times with CTTTIME . . . . . . . . . . . . . . . . . 174
Example of a Make File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

Chapter 12. Running a Program . . . . . . . . . . . . . . . . . . . . . . . . 179


Calling a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Using the CL CALL Command . . . . . . . . . . . . . . . . . . . . . . . . . 180
Example of Calling a Program Using the TFRCTL Command . . . . . . . . 181
Example of Running a Program from a User-Created CL Command . . . . 183
Passing Parameters to a Program . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Processing Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Ending a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Managing Activation Groups . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
Specifying an Activation Group . . . . . . . . . . . . . . . . . . . . . . . . . 189
Presence of a Program on the Call Stack . . . . . . . . . . . . . . . . . . . . 192
Deleting an Activation Group . . . . . . . . . . . . . . . . . . . . . . . . . . 192
Reclaiming System Resources . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Run-Time Compliance with ANSI C++ Draft Semantics . . . . . . . . . . . 194
Managing Run-Time Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Managing the Default Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . 195

Part 4. Debugging Your Program . . . . . . . . . . . . . . . . . . . 199

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger . . . . . 201
Preparing for Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
Authorities Required for Using the Debugger . . . . . . . . . . . . . . . . . 201
Configuring the Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Starting the Debug Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Setting Debugger Ports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

Contents ix
Ending the Debug Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
Compiling Your C++ Program . . . . . . . . . . . . . . . . . . . . . . . . . 203
Setting Environment Variables for Debugging . . . . . . . . . . . . . . . . . 203
Starting a Debugging Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Starting the Debugger from an OS/2 Prompt . . . . . . . . . . . . . . . . . . 205
Starting the Debugger from WorkFrame . . . . . . . . . . . . . . . . . . . . 207
Ending the Debugging Session . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Locating Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Frequently Used Features of the Debugger . . . . . . . . . . . . . . . . . . . . 209
Using the Title Bar Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
Running a Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
Setting Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Writing Code That the Debugger Supports . . . . . . . . . . . . . . . . . . . 211
Debugger Performance Considerations . . . . . . . . . . . . . . . . . . . . . 212
Debugger Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

Chapter 14. Introducing the Primary Debugger Windows . . . . . . . . . 215


Using the Debug Session Control Window . . . . . . . . . . . . . . . . . . . . 215
File Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Breakpoints Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
Monitors Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Run Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Options Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Windows Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Help Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Using the Program View Window . . . . . . . . . . . . . . . . . . . . . . . . . 232
File Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
View Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Breakpoints Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Monitors Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Run Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Options Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
Windows Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Help Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242

Chapter 15. Introducing the Secondary Debugger Windows . . . . . . . . 243


Using the Call Stack Window . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
File Menu Choice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Options Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
Windows Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Help Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
Using the Local Variables Window . . . . . . . . . . . . . . . . . . . . . . . . 246
File Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247

x IBM VisualAge C++ for OS/400 C++ User’s Guide


Edit Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Options Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Windows Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Help Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Using the Monitor Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Using the Breakpoints List Window . . . . . . . . . . . . . . . . . . . . . . . . 250
File Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Edit Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Set Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Options Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Windows Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Help Menu Choices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254

Chapter 16. Using the ILE Source-Level Debugger . . . . . . . . . . . . . 255


Introducing the ILE Source-Level Debugger . . . . . . . . . . . . . . . . . . . 256
Debug Commands for the ILE Source-Level Debugger . . . . . . . . . . . . 256
Debug Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Preparing a Program for Debugging . . . . . . . . . . . . . . . . . . . . . . . . 258
Creating a Listing View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Creating a Statement View . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Starting the ILE Source-Level Debugger . . . . . . . . . . . . . . . . . . . . . 260
Setting Debug Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Adding and Removing Programs from a Debug Session . . . . . . . . . . . . . 261
Viewing the Program Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Viewing a Different Module . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Setting and Removing Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . 264
Setting and Removing Unconditional Breakpoints . . . . . . . . . . . . . . . 264
Setting and Removing Conditional Breakpoints . . . . . . . . . . . . . . . . 266
Removing All Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Stepping Through the Program . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Stepping Over Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Stepping Into Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Stepping Over Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Stepping Into Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Displaying the Value of Variables and Expressions . . . . . . . . . . . . . . . 274
Changing the Value of Scalar Variables . . . . . . . . . . . . . . . . . . . . . . 286
Equating a Name with a Variable, Expression, or Command . . . . . . . . . . 288
Sample Source for EVAL Commands . . . . . . . . . . . . . . . . . . . . . . . 288
Sample Source for Displaying System and Space Pointers . . . . . . . . . . . . 290
Sample Source for Displaying C++ Constructs . . . . . . . . . . . . . . . . . . 292

Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
The IBM VisualAge C++ for OS/400 Library . . . . . . . . . . . . . . . . . . . 295

Contents xi
The IBM VisualAge C++ for OS/2 Library . . . . . . . . . . . . . . . . . . . . 295
The IBM VisualAge C++ for OS/400 BookManager Library . . . . . . . . . . 295
C and C++ Related Publications . . . . . . . . . . . . . . . . . . . . . . . . . . 296
IBM AS/400 Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
IBM OS/2 2.1 Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
IBM OS/2 3.0 Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Other Books You Might Need . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
BookManager READ/2 Publications . . . . . . . . . . . . . . . . . . . . . . 297
Non-IBM Publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299

xii IBM VisualAge C++ for OS/400 C++ User’s Guide


Notices
Any reference to an IBM licensed program in this publication is not intended to state
or imply that only IBM’s licensed program may be used. Any functionally equivalent
product, program or service that does not infringe any of IBM’s intellectual property
rights may be used instead of the IBM product, program, or service. Evaluation and
verification of operation in conjunction with other products, except those expressly
designated by IBM, is the user’s responsibility.

IBM may have patents or pending patent applications covering subject matter in this
document. The furnishing of this document does not give you any license to these
patents. You can send license inquiries, in writing, to the IBM Director of Licensing,
IBM Corporation, 500 Columbus Avenue, Thornwood, NY, 10594, USA.

Licensees of this program who wish to have information about it for the purpose of
enabling: (i) the exchange of information between independent created programs and
other programs (including this one) and (ii) the mutual use of the information which
has been exchanged, should contact IBM Canada Ltd., Department 071, 1150
Eglinton Avenue East, North York, Ontario M3C 1H7, Canada. Such information
may be available, subject to appropriate terms and conditions, including in some cases
payment of a fee.

Programming Interface Information


This book is intended to help you create AS/400 C++ applications using the
VisualAge C++ for OS/400 product. It primarily documents General-Use Program-
ming Interface and Associated Guidance Information provided by the VisualAge C++
for OS/400 product.

General-Use programming interfaces allow the customer to write programs that obtain
the services of the VisualAge C++ for OS/400 compiler, debugger, browser, and class
libraries.

However, this book also documents Diagnosis, Modification, and Tuning Information,
which is provided to help you debug your programs.

Attention: Do not use this Diagnosis, Modification, and Tuning Information as a pro-
gramming interface because it is subject to change.

Diagnosis, Modification, and Tuning Information is identified where it occurs, either


by an introductory statement to a chapter or section.

 Copyright IBM Corp. 1995 xiii


Trademarks and Service Marks
The following terms are trademarks of International Business Machines Corporation
in the United States or other countries or both:
AnyNet Operating System/2
Application System/400 Operating System/400
AS/400 OS/2
BookManager OS/400
C Set++ Presentation Manager
COBOL/400 READ/2
C/400 RPG/400
IBM SAA
ILE VisualAge
Integrated Language Environment Workplace Shell
Library Reader 400

xiv IBM VisualAge C++ for OS/400 C++ User’s Guide


About this Book
IBM VisualAge C++ for OS/400 offers a productive application development environ-
ment based on the C++ programming language which supports an object-oriented
design approach. Its many tools provide the means to build productive applications
that exploit the strengths of both the OS/2 and the OS/400 platforms.

This book describes how to use IBM VisualAge C++ for OS/400 to compile, bind,
and debug C++ applications that run in the Integrated Language Environment (ILE)
on the AS/400. It explains the steps required to perform these tasks, and introduces
the tools that are specific to developing OS/400 applications with IBM VisualAge
C++ for OS/400.

For information about other AS/400 publications, see either of the following:
Ÿ The Publications Reference in the AS/400 Softcopy Library.
Ÿ The AS/400 Information Directory, a unique, multimedia interface to a searchable
database containing descriptions of titles available from IBM or from selected
other publishers, shipped with your system at no charge.

Who Should Use This Book


This book is written for application or system programmers who want to create
OS/400 ILE C++ applications from the OS/2 development environment, using
VisualAge C++ for OS/400.

It assumes you have a working knowledge of the C and C++ programming languages,
the OS/2 and OS/400 operating systems, and related products as described in
VisualAge C++ for OS/400 Read Me First!. You also need knowledge of ILE as
explained in the ILE Concepts.

How to Use this Book


Use this book for information on how to compile, bind, debug and manage applica-
tions with VisualAge C++ for OS/400

See the VisualAge C++ for OS/400 C++ Programming Guide for reference infor-
mation on the more technical aspects of the compiler and advanced programming
techniques

 Copyright IBM Corp. 1995 xv


How to Read Syntax Diagrams

How to Read the Syntax Diagrams


This book uses two methods to show syntax. One is for commands, preprocessor
directives, and statements; the other is for compiler options.

Syntax for Commands, Preprocessor Directives, and Statements


Ÿ Read the syntax diagrams from left to right, from top to bottom, following the
path of the line.
The 55─── symbol indicates the beginning of a command, directive, or statement.
The ───5 symbol indicates that the command, directive, or statement syntax is
continued on the next line.
The 5─── symbol indicates that a command, directive, or statement is continued
from the previous line.
The ───5% symbol indicates the end of a command, directive, or statement.
Diagrams of syntactical units other than complete commands, directives, or state-
ments start with the 5─── symbol and end with the ───5 symbol.
Note: In the following diagrams, STATEMENT represents a C or C++ command,
directive, or statement.
Ÿ Required items appear on the horizontal line (the main path).
55──STATEMENT──required_item─────────────────────────────────────5%

Ÿ Optional items appear below the main path.


55──STATEMENT──┬───────────────┬─────────────────────────────────5%
└─optional_item─┘

Ÿ If you can choose from two or more items, they appear vertically, in a stack.
If you must choose one of the items, one item of the stack appears on the main
path.
55──STATEMENT──┬─required_choice1─┬──────────────────────────────5%
└─required_choice2─┘

If the items are optional, the entire stack appears below the main path.
55──STATEMENT──┬──────────────────┬──────────────────────────────5%
├─optional_choice1─┤
└─optional_choice2─┘

The item that is the default appears above the main path.

xvi IBM VisualAge C++ for OS/400 C++ User’s Guide


How to Read Syntax Diagrams

┌─default_item───┐
55──STATEMENT──┴─alternate_item─┴────────────────────────────────5%

Ÿ An arrow returning to the left above the main line indicates an item that can be
repeated.
┌──
─────────────────┐
55──STATEMENT───6─repeatable_item─┴───────────────────────────────5%

A repeat arrow above a stack indicates that you can make more than one choice
from the stacked items, or repeat a single choice.
Ÿ Keywords appear in nonitalic letters and should be entered exactly as shown (for
example, pragma).
Variables appear in italicized lowercase letters (for example, identifier). They
represent user-supplied names or values.
Ÿ If punctuation marks, parentheses, arithmetic operators, or other such symbols are
shown, you must enter them as part of the syntax.
Note: The white space is not always required between tokens, but it is recommended
that you include at least one blank between tokens unless specified otherwise.

The following syntax diagram example shows the syntax for the #pragma comment
directive. (See VisualAge C++ for OS/400 C++ Language Reference for information
on the #pragma directive.)

.1/ .2/ .3/ .4/ .5/ .6/ .9/ .1ð/


55─#──pragma──comment──(─┬─────compiler────────────────────────┬──)─5%
│ │
├─────date────────────────────────────┤
│ │
├─────timestamp───────────────────────┤
│ │
└──┬──copyright──┬──┬─────────────────┤
│ │ │ │
└──user───────┘ └──,─"characters"─┘

.7/ .8/

The syntax diagram is interpreted in the following manner:


.1/ This is the start of the syntax diagram.
.2/ The symbol # must appear first.
.3/ The keyword pragma must appear following the # symbol.

About this Book xvii


.4/ The keyword comment must appear following the keyword pragma.
.5/ An opening parenthesis must be present.
.6/ The comment type must be entered only as one of the types indicated:
compiler, date, timestamp, copyright, or user.
.7/ If the comment type is copyright or user, and an optional character string
is following, a comma must be present after the comment type.
.8/ A character string must follow the comma.
.9/ A closing parenthesis is required.
.1ð/ This is the end of the syntax diagram.

The following examples of the #pragma comment directive are syntactically correct
according to the diagram shown above:
#pragma comment(date)
#pragma comment(user)
#pragma comment(copyright,"This text will appear in the module")

Syntax for Compiler Options


Ÿ Optional elements are enclosed in square brackets [ ].
Ÿ When you have a list of items from which you can choose one, the logical OR
symbol (|) separates the items.
Ÿ Variables appear in italicized lowercase letters (for example, num).

Examples
Syntax Possible Choices
/L[+|-] /L
/L+
/L-
/Lt"string" /Lt"Listing File for Program Test"
Note that, for options that use a plus (+) or minus (-) sign, if you do not specify a
sign, the plus is assumed. For example, the /L and /L+ options are equivalent.

Highlighting Conventions
The following highlighting conventions are used in this book:
Bold Identifies commands, keywords, files, directories, and other items
whose names are predefined by the system.

xviii IBM VisualAge C++ for OS/400 C++ User’s Guide


How to Get Help

Italics Identify parameters whose actual names or values are to be supplied by


the programmer. Italics are also used for the first mention of new
terms that are defined in the glossary.
Example Identifies examples of specific data values, examples of text similar to
what you might see displayed, examples of portions of program code,
messages from the system, or information that you should actually
type.

Icons Used in This Book


The VisualAge C++ for OS/400 library uses icons to let you quickly scan pages for
key concepts, examples, cross-references, and other information.

This icon identifies examples that illustrate how to use a particular language feature
or other concept presented in the book.

This icon identifies cross-references to related information in this or other books.

How to Get Help


Three kinds of online information are available while you are using VisualAge C++
for OS/400:
Contextual help
Contextual help is available throughout VisualAge C++ for OS/400. This
help tells you all about the elements that you see in the interface,
including menus, entry fields, and pushbuttons.
How Do I... help
Many of the common tasks that you want to perform with VisualAge C++
for OS/400 are described in How Do I... help. The How Do I... help for
a task gives you step-by-step instructions for completing the task. There
is overall How Do I... help for VisualAge C++ for OS/400, as well as
individual task lists for each of its components.
Online documents
These are complete documents, like the one you are reading now, pre-
sented online. These documents contain detailed information on the dif-
ferent aspects of VisualAge C++ for OS/400. For your convenience, the
online documents are presented in two formats:
Ÿ BookManager format. See “BookManager Books” on page xxi
for details on how to access online documents in this format.
Ÿ Standard format. See “Getting Help Inside VisualAge C++ for
OS/400” on page xx for instructions on opening standard format doc-
uments from inside VisualAge C++ for OS/400. See “Getting Help

About this Book xix


How to Get Help

from the Command Line” on page xxi for instructions on opening


standard format documents from the command line.
The following documents are available in standard format:
– VisualAge C++ for OS/400 C++ User’s Guide
– VisualAge C++ for OS/400 C++ Programming Guide
– VisualAge C++ for OS/400 C++ Language Reference
– VisualAge C++ for OS/400 IBM Open Class Library and IBM
Access Class Library for OS/400 User’s Guide
– VisualAge C++ for OS/400 IBM Open Class Library and IBM
Access Class Library for OS/400 Reference
– VisualAge C++ for OS/400 C Library Reference
For a list of the VisualAge C++ for OS/400 documents that are
available in BookManager format, see “Bibliography” on page 295.

Getting Help Inside VisualAge C++ for OS/400


All three kinds of help are available directly within the VisualAge C++ for OS/400
interface:
Ÿ To get general contextual help for the component of VisualAge C++ for OS/400
that you are using, press F1 anywhere in the window.
Ÿ To get contextual help on a particular menu, menu item, or button, highlight the
element and press F1.
Ÿ To get access to all of the help information that is available to you in a particular
window, click on Help in the menu bar at the top of the window. This menu
includes the following selections:
– Help Index, an alphabetical list of all of the help topics that are available
from this window
– General Help, overall help for the window
– Using Help, general information about the help facility
– How Do I... help for the component
– Product Information, a dialog that shows the level of VisualAge C++ for
OS/400 being used
Ÿ To get detailed information, open the Information folder in the VisualAge C++
for OS/400 folder. In this folder you will find icons for a variety of online docu-
ments that describe, in detail, the different aspects of VisualAge C++ for OS/400.
To open a particular online document, double click on its icon.

xx IBM VisualAge C++ for OS/400 C++ User’s Guide


How to Get Help

Getting Help from the Command Line


You can look at the online documents by issuing the view command from an OS/2
command line. The installation routine stores the online document files in the
\CTTAS\HELP directory.

To view the VisualAge C++ for OS/400 C++ Language Reference, for example, make
C:\CTTAS\HELP your current directory (substituting the drive where you installed
VisualAge C++ for OS/400 for C:) and enter the following command:
VIEW CTTLRM.INF

If you want to get information on a specific topic, you can specify a word or a series
of words after the file name. If the words appear in an entry in the table of contents
or the index, the online document is opened to the associated section.

For example, if you want to read the section on operator precedence in VisualAge
C++ for OS/400 C++ Language Reference, you can enter the following command:
VIEW CTTLRM.INF OPERATOR PRECEDENCE

BookManager Books
In addition to standard format, the online documents are also available in
BookManager format. In this format they can be read using the BookManager
READ/2 product (program number 73F6023).

VisualAge C++ for OS/400 comes complete with the IBM Library Reader, which
allows you to read BookManager books without having to install the complete
BookManager READ/2 product.

Like the standard format, the BookManager format features hypertext links and a
search utility.

About this Book xxi


How to Get Help

xxii IBM VisualAge C++ for OS/400 C++ User’s Guide


Part 1. Developing OS/400 Applications with
WorkFrame
The chapters in this part describe how to build OS/400 C++ applications using IBM
WorkFrame, a fully-customizable application-development environment integrated
with the OS/2 Workplace Shell. Topics include:
Ÿ Introducing WorkFrame
Ÿ Using WorkFrame with VisualAge C++ for OS/400
Ÿ Creating OS/400 C++ applications with WorkFrame

 Copyright IBM Corp. 1995 1


2 IBM VisualAge C++ for OS/400 C++ User’s Guide
Overview of the WorkFrame Development Environment

1 Introducing WorkFrame

IBM WorkFrame is a fully-customizable application-development environment that


puts all your tools at your fingertips. It offers an interface that simplifies the process
of building and organizing software projects.

This chapter introduces you to the WorkFrame development environment. Topics


include:
Ÿ An overview of the WorkFrame development environment
Ÿ What you need to know to get started with WorkFrame
Ÿ How you can customize WorkFrame
Ÿ Where to find help and documentation for using and customizing WorkFrame

Overview of the WorkFrame Development Environment


WorkFrame is an extendable collection of objects and actions that organize your code
into projects. The project is the core of the WorkFrame environment. It
encapsulates all the objects you need to build a single target. Each project is repres-
ented by an associated icon, as shown below:

Figure 1. Project Icon

Each project has an associated set of actions (like Edit, Compile, Browse, and
Debug) that you can easily access and customize. You set options for actions quickly
through a graphical user interface. When you later invoke an action, the corre-
sponding options are in effect. For example, when you invoke the Compile action
from a pop-up or pull-down menu, WorkFrame invokes the compiler with your preset
options.

Any given project can contain many different types of OS/2 and OS/400 objects, such
as source files, browser files, make files, modules, programs, and service programs.
WorkFrame lets you invoke actions on objects based on their type.

 Copyright IBM Corp. 1995 3


Getting Started With WorkFrame

The contents of a typical OS/400 project called TEST are shown in Figure 2 on
page 4,

Figure 2. Objects Contained in Project TEST

Settings for projects and other WorkFrame objects are accessible from a Settings
notebook, as with any other Workplace Shell object.

Since no single development environment is likely to satisfy the needs of all software
developers, WorkFrame is not a tightly-integrated development environment. Rather,
WorkFrame allows the plug-and-play addition of new or upgraded tools without
changing the rest of the environment.

Getting Started With WorkFrame


Before you start developing applications in the WorkFrame environment, you need to
be familiar with a number of WorkFrame-related concepts and tasks. Whether your
projects target the OS/2 or the OS/400 run-time environment, WorkFrame's basic
functionality is the same. To avoid duplicate information, this book describes the
actions that are specific to developing OS/400 applications with WorkFrame.

See Part 1 of the VisualAge C++ for OS/2 User’s Guide for an in-depth discussion
of the WorkFrame development environment. It introduces you to WorkFrame, and
describes the main project-related tasks, such as managing projects, setting up project
tools, monitoring projects, and building a project target. Advanced topics explain

4 IBM VisualAge C++ for OS/400 C++ User’s Guide


Getting Started With WorkFrame

how to take advantage of Project Smarts, and how to work with multiple Project
Access Methods (PAMs).

Try the Compile-Edit-Debug scenario in the VisualAge C++ Touch sample


project, described in Part 1 of the VisualAge C++ for OS/2 User’s Guide, to get first
hands-on experience with WorkFrame Although this is an OS/2 application, the basic
steps of working with a project are the same, whether you develop OS/2 or OS/400
applications.

WorkFrame Terms and Concepts You Need to Know


The following WorkFrame terms and concepts are explained in detail in the
VisualAge C++ for OS/2 User’s Guide. They represent the basis for application devel-
opment from the WorkFrame environment.
Action
An action is a description of a tool or a function of a tool that can be used to manip-
ulate a project's parts, or participate in a build. Actions are grouped into classes so
that tools with similar function can be described and grouped together in project
pop-up menus. Entries in an action's Settings notebook determine how tools become
actions in the WorkFrame environment. Examples of actions are Edit, Compile, and
Bind.
Default Action
Each action class has a default action. It is defined as the first action listed in the
class.
Default Project
WorkFrame recognizes a single default project in the system, from which other
projects can inherit.
Project
The project represents the complete set of data and actions you need to build a single
target, such as a program, or a service program. Projects are simply files to the oper-
ating system. Each project has a corresponding physical file in the OS/2 files system
Project Access Method
A Project Access Method (PAM) is a mechanism that gives WorkFrame access to the
project parts. OS/400 projects use the default PAM set up for OS/2 projects.
Project Hierarchy
Applications most likely consist of a hierarchy of projects, rather than a single
project. Separate projects for each target can be nested. Their hierarchical organiza-
tion determines the way in which projects are built.
Project Icon view
This view has the following controls: System menu, Project toolbar, Menu bar, Parts
filter, Parts container, and Monitor.

Chapter 1. Introducing WorkFrame 5


Customizing WorkFrame

Project Inheritance
Projects can share actions, environment variables, and types by inheriting the Tools
setup of one or more projects.
Project Monitor
The project Monitor is an extension of the project view. It monitors the output of
actions run from a project.
Project Parts
Project parts are the data objects that make up the project.
Project Settings
This notebook contains settings for the project. It has standard Workplace Shell
pages, along with pages specific to a WorkFrame project.
Project Smarts
Project Smarts is a catalog of skeleton applications that can be used as a base for
OS/2 applications. It can be extended to include new skeletons, such as OS/400 appli-
cations, as well.
Project Target
A target is a specially designated project part that is the result of a Build action
invoked on the project. Two WorkFrame utilities help you build a target: Build and
MakeMake. The Build utility dynamically builds project targets and manages make
files. MakeMake is WorkFrame's make file creation utility.
Project Views
A project has five views: Icon view, Details view, Tree view, Tools setup, and Set-
tings.
Project Template
A project template is an object that can be used as a model to create projects with
similar settings and contents.
Tools setup
A project's Tools setup defines the actions, environment variables, and types that are
available to the project.

Customizing WorkFrame
You can customize WorkFrame in many ways to suit the needs of your application,
or to satisfy particular requirements in your development environment. You can inte-
grate your own tools, and create ready-to-use application templates from Project
Smarts, an extendible application wizard.

Whether you are planning to develop applications for OS/2 or for OS/400, custom-
izing WorkFrame requires the same steps. See the VisualAge C++ for OS/2 User’s

6 IBM VisualAge C++ for OS/400 C++ User’s Guide


Getting Help for WorkFrame

Guide for a complete discussion of how to customize projects, integrate your own
tools, and create projects from templates.

Getting Help for WorkFrame


You can access two types of online help while using WorkFrame:
Ÿ Contextual online help, which gives you help from within WorkFrame
Ÿ How Do I... help, which gives you step-by-step instructions on how to perform a
number of project-related tasks.

Using Contextual Help


Help on how to use any menu choice, window, or control is available through online
context-sensitive help. You can access it in one of the following ways:
Ÿ Select an item from a Help pop-up or pull-down menu in any WorkFrame
window. The Help menu in a project container gives you access to VisualAge
C++ for OS/400 manuals, How Do I... information, and context-sensitive help for
WorkFrame.
Ÿ Press F1 from any WorkFrame window to get help on the current field.
Ÿ Highlight a menu item and press F1 to get help on the menu item.
Ÿ Highlight the name of an action on a pop-up or pull-down menu and press F1 for
help on the action, where supported.
Ÿ Click on the Help pushbutton, where available.

Using "How Do I..." Information


Refer to How Do I... help when you need to accomplish a specific task, or when you
want to explore WorkFrame functions. You can access the How Do I... information
in several ways:
Ÿ From the Help pull-down menu, select How Do I... → WorkFrame.
Ÿ Open the How Do I... folder located in the main VisualAge C++ folder on your
desktop, and select the WorkFrame How Do I... icon.
Ÿ From within the VisualAge C++ for OS/400 Project Template - Icon View
window, click on the How Do I? button on the toolbar

Chapter 1. Introducing WorkFrame 7


Getting Help for WorkFrame

8 IBM VisualAge C++ for OS/400 C++ User’s Guide


Choosing Development Tools

2 Using WorkFrame with VisualAge C++ for OS/400

This chapter explains how to develop OS/400 C++ applications with WorkFrame.
Topics include:
Ÿ Choosing the appropriate WorkFrame tools
Ÿ WorkFrame actions specific to OS/400 application development
Ÿ Developing client/server applications with WorkFrame

Choosing the Appropriate Development Tools


With VisualAge C++ for OS/400 you can develop C++ applications for OS/2, for
OS/400, or for both, in a client/server relationship. In either case, the WorkFrame
environment lets you access the appropriate development tools.

Although the tools you use may be platform specific, the functionality of WorkFrame
is always the same. To illustrate why different tools may be needed for similar tasks,
consider the following cases:
1. Compiling and linking a C++ source file for the OS/2 run-time environment
requires the following steps:
a. A source file abc.cpp is compiled by the OS/2 C++ compiler into an object
module abc.obj.
b. The linker is invoked and creates the executable abc.exe, which runs on an
OS/2 workstation.
2. Compiling and binding the same C++ source file to run in an OS/400 environ-
ment requires the following steps:
a. The source file abc.cpp, located on your OS/2 workstation, is compiled by
the C++ cooperative compiler into a module object ABC, located on the
AS/400.
(You must establish a connection between your OS/2 workstation and an
AS/400 before invoking the compiler, if you want to create OS/400 objects)
b. On the AS/400, the binder binds this module object into a program object
ABC, which runs on an AS/400.

In the first case, you need access to the C++ compiler for OS/2, the OS/2 Linker, and,
optionally, the VisualAge C++ for OS/2 Debugger.

 Copyright IBM Corp. 1995 9


Choosing Development Tools

In the second case, you need access to the C++ cooperative compiler, the OS/400
Binder, and, optionally, the VisualAge C++ for OS/400 Debugger.

Other tools, such as the editor or the browser, can be used in both cases, because they
are independent of an application's target platform.

Correspondence Between OS/2 and OS/400 Objects


The following table shows the correspondence between OS/2 and OS/400 objects:
Figure 3. Correspondence between OS/2 and OS/400 Objects

OS/2 OS/400
Object module (.OBJ) Module object (\MODULE)
Executable (.EXE) Program object (\PGM)
Dynamic link library (.DLL) Service program (\SRVPGM)
Library (.LIB) N/A
Help file (.HLP) N/A
Directory Library (\LIB)
Linker Binder

WorkFrame Actions are Context-Sensitive


When you select a file, and then press mouse button 2 to bring up its pop-up menu,
you see a list of relevant actions for this object. The actions are context-sensitive to
the type of file they are invoked on.

For example, the compile action for a C++ source file may let you choose between
several compilers. You select the one appropriate for your target run-time environ-
ment.

Your choice is more limited once you have compiled a source file:
Ÿ If you have compiled your source file into an OS/2 object module (.obj), you
invoke the OS/2 linker to link this file into an OS/2 executable (.exe)
Ÿ If you have compiled your source file into an OS/400 module object
(*MODULE), you invoke the OS/400 binder to bind this file into an OS/400
program (*PGM) or service program (*SRVPGM).

Figure 4 shows the groups of actions available for OS/2 and OS/400 projects.

10 IBM VisualAge C++ for OS/400 C++ User’s Guide


Choosing Development Tools

Figure 4. WorkFrame Actions for OS/2 and OS/400 Projects

Action OS/2 Projects OS/400 Projects


Build X X
Run X
Debug X X
Edit X X
Browse X X
View X X
Compile X X
Analyze X
Make X X
Visual X
Inspect X
MapSym X
Database X
Bind X X
MakeMake X X
Link X
Lib X
Package X
Brsmon X

See the VisualAge C++ for OS/2 User’s Guide for a description of the actions that
can be invoked for OS/2 objects.

Chapter 2. Using WorkFrame with VisualAge C++ for OS/400 11


WorkFrame Actions for OS/400 Projects

WorkFrame Actions for OS/400 Projects


Figure 5 shows the complete list of action groups that can be invoked when you
develop OS/400 C++ applications with WorkFrame.

Figure 5. WorkFrame Action Groups for OS/400 Applications

Each action group is associated with actions, or with specific tools. When you click
on the + sign to the left of an action group in the Tools setup window, a list of
action or tool icons is displayed. When you double-click on one of these icons, the
corresponding notebook opens, and you can specify parameters and options you want
to be in effect when the action or tool is invoked.

12 IBM VisualAge C++ for OS/400 C++ User’s Guide


WorkFrame Actions for OS/400 Projects

Select the Build action to build your project. You can choose between a normal build,
and rebuilding the entire project.

Select the Debug action to invoke the debugger.

Select the Edit action to invoke one of the editors available with VisualAge C++ for
OS/400 (VisualAge Editor, EPM, and System Editor).

Select the Browse action to invoke the browser, and the VisualAge Editor.

Select the Compile action to compile your project with the cooperative compiler.

Chapter 2. Using WorkFrame with VisualAge C++ for OS/400 13


Developing Client/Server Applications With WorkFrame

Select the Make action to invoke the Make utility

Select the MakeMake action to create a Make file

Select the View action to view your project

Select the Bind action to bind modules into programs or service programs.
Note: The actions shown above can be invoked if you have installed the entire
VisualAge C++ for OS/400 package. If you have chosen not to install all compo-
nents, some tools may not be available to you. On the other hand, you may have
configured additional tools into WorkFrame, such as your favorite editor. In this case,
clicking on the Edit action, for example, gives you access to this tool, as well.

Developing Client/Server Applications With WorkFrame


When developing applications that run on both OS/2 and OS/400, in a client/server
relationship, you may need access to all the actions listed in Figure 4 on page 10.

When you installed VisualAge C++ for OS/400 on your OS/2 workstation, two sepa-
rate folders were created on your desktop:
Ÿ VisualAge C++, which contains VisualAge C++ for OS/2
Ÿ VisualAge C++ for OS/400, which contains VisualAge C++ for OS/400 work-
station components

14 IBM VisualAge C++ for OS/400 C++ User’s Guide


Developing Client/Server Applications With WorkFrame

Each of these folders contains its own Project Template icon. In the VisualAge C++
folder, the project template is set up with all the actions available for OS/2 develop-
ment. In the VisualAge C++ for OS/400 folder, the project template is set up with all
the actions available for OS/400 development.

Instead of creating two separate projects for your OS/2 and OS/400 objects, you can
customize one of the two project templates, and add the actions specific to the other
platform to it. Another possibility is to create a project that inherits the actions from
both templates.

See the Project Smarts chapter in the VisualAge C++ for OS/2 User’s Guide for
information on customizing a project template.

See “Creating a Project With Multiple Inheritance” on page 30 for an example of


creating a project that inherits actions from two different project templates, and an
example of adding a new action to an existing action group.

Chapter 2. Using WorkFrame with VisualAge C++ for OS/400 15


Developing Client/Server Applications With WorkFrame

16 IBM VisualAge C++ for OS/400 C++ User’s Guide


Setting Up a Project

3 Creating OS/400 C++ Applications with WorkFrame

This chapter describes how to create OS/400 applications from the WorkFrame devel-
opment environment. Topics include:
Ÿ Setting up a WorkFrame project
Ÿ Creating and editing source files from within WorkFrame
Ÿ Setting compiler options and invoking the Compile action
Ÿ Setting binder options and invoking the Bind action
Ÿ Using the VisualAge Browser to browse source files
Ÿ Debugging an application from within WorkFrame
Ÿ Creating a Project with Multiple Inheritance
Ÿ Adding an Action to a Project

Setting Up a Project
When you create an application with WorkFrame, you begin by setting up a project.
The steps involved are:
1. Creating and naming a project
2. Designating a project target
3. Locating project parts
4. Optionally, customizing the project

Creating and Naming a Project


There are several ways to create a WorkFrame project, depending on the type of
project you have in mind:
Ÿ Create a project from the VisualAge C++ for OS/400 Project Template
Ÿ Create a project from another project
Ÿ Copy another project
Ÿ Install a project from Project Smarts

See the VisualAge C++ for OS/2 User’s Guide for a description of the project-
creation methods.

Creating an OS/400 Project


To create a project that already contains all OS/400-related actions and environment
variables, drag the VisualAge C++ for OS/400 Project Template from the main
VisualAge C++ for OS/400 folder, and drop it on the desktop.

To name the project, point to the newly created icon, press mouse button 2, and select
Settings from the pop-up menu, to open the VisualAge C++ for OS/400 - Settings
 Copyright IBM Corp. 1995 17
Setting Up a Project

notebook. Click on the General tab and type the project name in the Title entry
field, for example Test Project.

Note that the title bar of the Settings notebook now shows the new project name. In
our example, the title bar reads Test Project - Settings.

To modify the default project icon, click on the Edit... push-button, also located on
the General notebook page, and use the icon editor to make changes.

Designating a Project Target


To define the file that is ultimately produced when you build your project, click on
the Target page of the Settings notebook.

Type the name of the target object in the Name entry field, for example MYPROG. The
following table shows the valid OS/400 objects you can specify in this field:
Figure 6. Valid OS/400 Project Targets

OS/400 Object Type Field Entry


Module *MODULE module-name
Program *PGM program-name
Service Program *SRVPGM service-program-name

Note: When you specify the object name, you should omit the object type,
*MODULE, *PGM, or *SRVPGM.

WorkFrame supports a Run action for OS/2 executables, but not for OS/400 pro-
grams. Therefore, run options are not available if your target is an OS/400 program
object, and the Run options entry field cannot be used.
Note: You can launch OS/400 applications from an OS/2 command line by passing
the CL CALL command as a parameter on the CTTHCMD, for example
CTTHCMD CALL program-name

However, this is most often not useful, because screen output from the program you
call is not visible from the OS/2 workstation session.

If you want to use a make file to build your project target, type a file name in the
Makefile entry field, for example mymake.mak. When you use MakeMake to generate
a make file for the project, it will save the make file with the name specified in this
field.

18 IBM VisualAge C++ for OS/400 C++ User’s Guide


Setting Up a Project

Locating Project Parts


WorkFrame needs to know where to find the files that are part of your project. To
enter this information, click on the Location page in the Settings notebook.

To specify the source directories in which your project parts are located, type the
name(s) of one or more OS/2 workstation directories and OS/400 libraries in the
Source directories for project files entry field.

For example, the entry E:\SAMPLE indicates that project parts are located in directory
SAMPLE, on OS/2 workstation drive E:, and the entry G:\QSYS.LIB\DEMO.MYLIB.LIB
could indicate that project parts are located in library MYLIB, on an AS/400 that has
been assigned to drive G: on your OS/2 workstation.

All the files located in these directories (if any) are now part of the project, and are
shown in the project parts container, in the various View windows.
Note: Before you can access objects located on an AS/400 mounted drive, you must
have started Client Access/400 Optimized for OS/2 Client which provides the neces-
sary communication support.

See the Client Access/400 for OS/2 User Guide for information on how to assign
an AS/400 to an OS/2 workstation drive.

After selecting the source directories for project files, designate one of them as the
working directory. Type the directory name in the Working directory entry field, for
example E:\SAMPLE . When actions are executed, this directory is their current
directory, where any output files are created, by default.
Note: The working directory must be an OS/2 workstation directory. When actions
are executed, OS/400 modules, programs, and service programs will not be placed in
the working directory, but in a library on the AS/400 to which you are connected at
compile time.

Customizing the Project


The information entered on the Target and Location pages of the Settings notebook
is required for setting up a project. Additional notebook pages let you further cus-
tomize your project, unless you prefer to proceed with the default settings. These
notebook pages are listed below:
Monitor Page Use this page to customize the display of the monitor window.
The project monitor lets you monitor the output of the actions
that you run from your project.
See the VisualAge C++ for OS/2 User’s Guide for a detailed
description of the project monitor and its controls.

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 19


Creating and Editing Source Files

Inheritance Page Use this page to select one or more projects whose Tools setup
is to be inherited by the current project.
See the VisualAge C++ for OS/2 User’s Guide for a detailed
discussion of inheriting a Tools setup, and inheritance preced-
ence rules.
View Pages Use these pages to customize the display of the various views
of the main project.
See the VisualAge C++ for OS/2 User’s Guide for a
description of the push-buttons and entry fields on the Icon
view, Tree view, and Details view pages.
Sort Page Use this page to select the order in which project parts are
listed in each view of the project parts container.
See the VisualAge C++ for OS/2 User’s Guide for a
description of the push-buttons and entry fields on the Sort
page.
Menu Page Use this page to add, delete, or change the items in a pop-up-
menu for a selected object.
See the online help for a description of the push-buttons and
entry fields on the Menu page. To access the appropriate help
panel, open your project's Settings notebook at the Menu page
and click on the Help push-button at the bottom of the page.
File Page Use this page to enter the description of an object, or to view
the path and file name of an object.
See the online help for a description of the push-buttons and
entry fields on the File page. To access the appropriate help
panel, open your project's Settings notebook at the File page
and click on the Help push-button at the bottom of the page.
Window Page Use this page to customize the behavior of the project window.
See the online help for a description of the push-buttons and
entry fields on the Window page. To access the appropriate
help panel, open your project's Settings notebook at the
Window page and click on the Help push-button at the bottom
of the page.

Creating and Editing Source Files


To create source files for your project, or edit source files that are already part of the
project, you can invoke an editor directly from the project window.

20 IBM VisualAge C++ for OS/400 C++ User’s Guide


Creating and Editing Source Files

WorkFrame lets you invoke several editors. To look at your choices, click on the
Tools setup push-button on your Project toolbar. The Tools setup window appears,
and lists the actions available to your project.

Click on the + sign next to the Edit action, to display icons for the editors that have
been integrated into the WorkFrame environment.
Note: The editor listed first has been set up as the default editor. If you prefer a
different setup, you can make your favorite editor the default for this action.

See the VisualAge C++ for OS/2 User’s Guide for instructions on how to define
the default action for an action class.

Introducing the VisualAge Editor


The default editor for WorkFrame projects is the VisualAge Editor, a language-
sensitive, programmable editor which lets you:
Ÿ Create and edit source files
Ÿ Start other tools, such as the compiler, browser, and debugger.

There are several ways to invoke the VisualAge Editor:


Ÿ From within a WorkFrame project, as described below
Ÿ Using the lxpm command from an OS/2 command line
Ÿ By double-clicking on the Editor icon in the VisualAge C++ for OS/400 Tools
folder

See the VisualAge C++ for OS/2 User’s Guide for a full description of the
VisualAge Editor.

Invoking an Editor from within WorkFrame


To invoke an editor from the project window, choose one of the following methods:
Ÿ To run the default editor without loading a particular file, click on the Edit
button, from the Project toolbar.
Ÿ To invoke the editor of your choice, select Edit from the Project pull-down
menu or the container pop-up in the project window.
Ÿ To create a new file in your working directory, drag a data file template onto the
project, from the Templates folder.
To edit the file, point to it and press mouse button 2. Click on the arrow next to
the Edit action in the pop-up menu, and select one of the editors shown.

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 21


Compiling Source Files

Compiling Source Files


Before compiling source files from within a project, you need to set a number of
compiler options, unless you prefer WorkFrame's default settings. You set compiler
options either from the Build Smarts window, or from a project's Compiler Options
notebook.

Setting Compiler Options in Build Smarts


Build Smarts is a fast path for setting options for a number of actions that affect the
way your project target is built.

The options set in the Build Smarts window are enabled by default, and work in
combination with the options that are set for the individual actions themselves. In
case of conflicts, options set in Build Smarts override settings in a project's Com-
piler Options notebook.

To disable or modify the Build Smarts settings, click on the Build Smarts button on
the Project toolbar and make the required changes in the Build Smarts window.

If you need help for a particular option in the Build Smarts window, click on the
corresponding button or entry field, and then click on the Help button at the bottom
of the window.

Effect of Build Smarts Options


The online help describes the effect of Build Smarts options on OS/2 project targets.
These options also apply to OS/400 project targets, with the exception of the Perform-
ance Analyzer. The following list shows the correspondence between options set in
the Build Smarts window, and the equivalent compiler options.
Debugger Selecting this option enables your application for debugging. It is
equivalent to specifying the /Ti and the /O- compiler options.
Browser Selecting this option enables your application for browsing with the
VisualAge Browser. It is equivalent to specifying the /Fb compiler
option.
Optimizer Selecting this option instructs the compiler to optimize your object
code. It is equivalent to specifying the /O compiler option.

Setting Compiler Options in the Compiler Options Notebook


The Compiler Options notebook of a project is another place where you can set
options that determine how the project target is built.
Note: If the options set in the Build Smarts window are enabled, they work in
combination with the options you set in the Compiler Options notebook. In case of
conflicting options, those set in the Build Smarts window take precedence.

22 IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiling Source Files

Setting options from the Compiler Options notebook involves the following steps:
1. From the Project toolbar, click on the Tools setup button to display the list of
actions available to your project.
Note: If the last use of the Tools setup was to set up variables, the Variables
window is displayed.
2. Click on the + sign next to the Compile action, and double-click on the
VisualAge C++ for OS/400 Compiler icon, to open the Compiler Options note-
book.
3. Fill in the required information on each page of this notebook, unless you want
to proceed with the default options that have already been set.
If you need help for a particular option, click on the corresponding button or
entry field, and then click on the Help button at the bottom of the page, or press
F1.
If you need help for a particular group of options, double-click on the corre-
sponding notebook tab, and then click on the Help button at the very bottom of
the notebook, or press F1.
4. Close the notebook to return to the main project window.

Invoking the Compiler from within WorkFrame


Before you invoke the compiler for the first time in a WorkFrame session, you must
have established a connection between your OS/2 workstation and an AS/400, unless
you only want to check the syntax of your source code.

See “Establishing an AS/400 Connection Before Compiling and Binding” on


page 40 for details on connecting an OS/2 workstation to an AS/400.

From within your WorkFrame project, you invoke the compiler through the Compile
action. You launch the Compile action in one of the following ways:
Ÿ High-light the source file(s) you want to compile, then pull down the Selected
menu from the menu bar, and select Compile.
Ÿ High-light the source file(s) you want to compile, then press mouse-button 2 to
display the pop-up menu of possible actions for one of the files, and select
Compile.

To select several adjacent files:


1. Highlight the first file.
2. Hold down the Shift-key, and highlight the last file in the group.

The entire group is now selected.

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 23


Creating Programs and Service Programs

To select files that are not adjacent:


1. Highlight the first file.
2. Hold down the Ctrl-key, and highlight additional files.

Creating Programs and Service Programs


The module objects that result from compiling source files can be bound into either
programs (*PGM) or service programs (*SRVPGM). From within a WorkFrame
project, you invoke the binder through its associated action.

The Bind action has both file and project scope. This means that it can be invoked
for a particular module, or for the entire project. The MakeMake utility, for example,
uses the file-scope option selection.

See the chapters in Part 3, “Binding and Running Your Program” on page 125 if
you are not familiar with the concept of creating programs and service programs.

Setting Binder Options


Before you bind module objects into programs or service programs, you set the
options that determine how the modules are bound in the CRTPGM or
CRTSRVPGM notebook of a project.

Setting options in these notebooks involves the following steps:


1. From the Project toolbar, click on the Tools setup button to display the list of
actions available to your project.
2. Click on the + sign next to the Bind action, and double-click on either the
CRTPGM or the CRTSRVPGM icon to open the corresponding notebook.
Note: Double-clicking opens the notebook to set options with project scope. If
you want to set options with file scope, instead, click the right mouse-button and
select File options from the pop-up menu.
3. Fill in the required information on each page of the notebook, unless you want to
proceed with the default options that have already been set.
If you need help for a particular option, click on the corresponding button or
entry field, and then click on the Help button at the bottom of the page.
If you need help for a particular group of options, double-click on the corre-
sponding notebook tab, and then click on the Help button at the very bottom of
the notebook.
4. Close the notebook to return to the main project window.

24 IBM VisualAge C++ for OS/400 C++ User’s Guide


Browsing Source Code

Invoking the Binder


From within your WorkFrame project, you invoke the binder through the Bind action.

You launch the Bind action in one of the following ways:


Ÿ Pull-down the Project menu and select Bind
Ÿ High-light the module(s) you want to bind, then pull down the Selected menu
from the menu bar, and select Bind.
Ÿ High-light the module(s) you want to bind, then press mouse-button 2 to display
the pop-up menu of possible actions for one of the files, and select Bind.

To select several adjacent files, highlight the first file. Then hold down the Shift-key
and highlight the last file in the group. The entire group is selected. To select files
that are not adjacent, highlight the first file. Then hold down the Ctrl-key and high-
light additional files.
Note: Before you invoke the binder for the first time in a WorkFrame session, you
must have established a connection between your OS/2 workstation and an AS/400.

See “Establishing an AS/400 Connection Before Compiling and Binding” on


page 40 for details on connecting an OS/2 workstation to an AS/400.

Browsing Source Code


A browser is a development tool that helps you navigate through source code. The
VisualAge Browser lets you:
Ÿ List program components by type (for example, all classes)
Ÿ Graphically view relationships between program components, such as class-
inheritance hierarchies, function calls, and included files
Ÿ View and edit source code associated with a selected program component
Ÿ Look up online documentation for a class or a class member

See the VisualAge C++ for OS/2 User’s Guide for a full description of the
VisualAge Browser.
Note: Before you can browse C++ source code, you must compile the source file
with the /Fb compiler option. This results in the creation of a browser file with the
extension .pdb.

See “Compiling Source Files” on page 22 for details on compiling source files
from a WorkFrame project. See Part 2, “Compiling Your Program” on page 35 for a
full description of compiling with the VisualAge C++ for OS/400 cooperative com-
piler

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 25


Browsing Source Code

Restrictions When Browsing OS/400 Applications


The VisualAge C++ for OS/2 User’s Guide describes how to browse OS/2 applica-
tions. The following differences exist in the types of input files you can use when
browsing OS/400 applications:
Figure 7. Browsing OS/2 and OS/400 File Types

File Type File Extension Database File OS/2 OS/400


Compiler generated browser .pdb .PDB X X
file
C++ source file .cpp X X
Dynamic link library .DLL .PDD X
Executable file .EXE .PDE X
Library file .LIB .PDL X

Note: While you can specify the /BROWSE option for the OS/2 Linker, the same is
not true for the OS/400 Binder, and you cannot browse the following OS/400 file
types:
Ÿ *MODULE
Ÿ *PGM
Ÿ *SRVPGM

Invoking the VisualAge Browser


There are several ways to invoke the VisualAge Browser:
Ÿ From within a WorkFrame project, as described below
Ÿ Using the icsbrs command from an OS/2 command line
Ÿ By double-clicking on the browser icon in the VisualAge C++ for OS/400 Tools
folder
Ÿ From within the VisualAge Editor
Ÿ From within the Cooperative Debugger

See the VisualAge C++ for OS/2 User’s Guide for detailed information on the
various methods of loading browser files.

Invoking the Browser from within WorkFrame


From inside a WorkFrame project, you launch the Browse action in one of the fol-
lowing ways:
Ÿ Pull down the Project menu and select Browse.

26 IBM VisualAge C++ for OS/400 C++ User’s Guide


Debugging an OS/400 Application

Specify the name of the file you want to browse in the Load Database window
of the browser.
Ÿ High-light the file(s) you want to browse, then pull down the Selected menu
from the menu bar, and select Browse.
Ÿ High-light the file(s) you want to browse, then press mouse-button 2 to display
the pop-up menu of possible actions for one of the files, and select Browse.

Debugging an OS/400 Application


A debugger is a development tool that helps you detect and diagnose errors in your
code.

OS/400 C++ applications can be debugged using the VisualAge C++ for OS/400
Debugger from an OS/2 workstation, or using the ILE Source-Level Debugger on the
AS/400. Both debuggers let you:
Ÿ Set breakpoints in your program
Ÿ Step into program instructions
Ÿ Display the values of variables
Ÿ Examine the call stack

With the VisualAge C++ for OS/400 Debugger, you perform these tasks from your
OS/2 workstation, while your application is running on an AS/400. See
Chapter 13, “Using the IBM VisualAge C++ for OS/400 Debugger” on page 201 for
a full description of the capabilities and functionality of this tool.

With the ILE Source-Level Debugger, you perform these tasks from the AS/400
where your application is running. See Chapter 16, “Using the ILE Source-Level
Debugger” on page 255 for a full description of the capabilities and functionality of
this tool.
Note: Before you can debug an OS/400 C++ application, you must compile its
source files with one of the /Ti options, which instruct the compiler to include debug
information in the program object.

See “/Ti” on page 108 for a full description of the debug options. See “Com-
piling Source Files” on page 22 for details on compiling source files from a
WorkFrame project. See Part 2, “Compiling Your Program” on page 35 for a full
description of compiling with the VisualAge C++ for OS/400 cooperative compiler

Preparing for Debugging with the VisualAge C++ for OS/400 Debugger
The VisualAge C++ for OS/400 Debugger is a client/server program that runs
cooperatively on an OS/2 workstation and an AS/400. Before invoking it, you must
perform the following steps:

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 27


Debugging an OS/400 Application

Ÿ To start the debug server on the AS/400 on which you plan to run your applica-
tion, type the command STRDBGSVR on the AS/400 command line.
Ÿ To configure the debugger client:
– Specify the AS/400 where your application will be running
– Specify the search path for the source code files
– Specify the port used to connect to the AS/400
See Chapter 13, “Using the IBM VisualAge C++ for OS/400 Debugger” on
page 201 for information on the authorities required for using the debugger, and
for details on configuring the debugger, setting up debugger ports and environ-
ment variables, and specifying command line options.

Invoking the Debugger


There are several ways to invoke the debugger:
Ÿ From within a WorkFrame project, as described below
Ÿ Using the ipmdas command from an OS/2 command line
Ÿ From the the debugger icon in the VisualAge C++ for OS/400 Tools folder

Invoking the Debugger from within WorkFrame


If you have not set the environment variable ICCASDEBUGHOST in your CONFIG.SYS
file, you have to supply information about the target AS/400 through the /e debugger
option:
1. Click on Tools setup
2. Click on the Debug action
3. Double-click on the debugger icon
4. In the Parameters entry field of the Debug notebook type /ehostname where
hostname represents the TCP/IP name of the target AS/400 system.
5. Close the Debug notebook.

From within a WorkFrame project you launch the Debug action in one of the fol-
lowing ways:
Ÿ Pull down the Project menu and select Debug
Ÿ High-light the file(s) you want to debug, then pull down the Selected menu from
the menu bar, and select Debug
Ÿ High-light the file(s) you want to debug, then press mouse-button 2 to display the
pop-up menu of possible actions for one of the files, and select Debug

Once the debugger has been invoked:

28 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the MakeMake Utility

1. In the Startup Information window of the debugger, specify the name of the
program you want to debug, and the name of your interactive job.
2. Start the application you want to debug by typing CALL program-name on an
AS/400 command line, where program-name represents the name of the program
you want to debug
3. Click on OK in the Debugger Message window

Using the MakeMake Utility for OS/400 Projects


The MakeMake utility generates make files for your project. It creates make files
based on the actions and source files associated with your project.

See the VisualAge C++ for OS/2 User’s Guide for a full description of this utility.

For MakeMake to work properly when building OS/400 targets, you must specify two
environment variables:
ICCAS_DRIVE Specifies the mounted drive to which the AS/400 has been
assigned, for example I
ICCAS_DIR Specifies the target AS/400 library, for example MYLIB
Note: The drive must be mounted at the root, so that the information provided by
these environment variables can be used to build a fully qualified path.

If you do not want to set these environment variables in your CONFIG.SYS file, you
can set them in the Tools setup window of your WorkFrame project:
1. Click on the Tools setup button in your project window
2. Pull down the Variables menu
3. Select Add to open the Add Environment Variable window.
4. Enter ICCAS_DRIVE in the Name entry field, and specify the mounted drive to
which your target AS/400 has been assigned in the String entry field, for
example I
5. Enter ICCAS_DIR in the Name entry field, and specify the name of your target
AS/400 library in the String entry field, for example MYLIB

Attention: The MakeMake notebook lets you specify selections with project scope
for modules and service programs. These selections are not used when the CRTPGM
and CRTSRVPGM commands are invoked. Instead, the file-scope settings for
modules and service programs are used.

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 29


Project With Multiple Inheritance

Creating a Project With Multiple Inheritance


When you create a new project from a project template, as described in “Creating
and Naming a Project” on page 17, the new project inherits all actions and environ-
ment variables contained in the template. The same is true when you create a new
project from any other existing project. A project can even inherit from several
project templates or existing projects.

The following example shows how to create a project that can access both OS/2 and
OS/400 specific actions and object types.

See the VisualAge C++ for OS/2 User’s Guide for a complete discussion of inher-
iting the Tools setup of an existing project.

Inheriting from OS/2 and OS/400 Project Templates


The VisualAge C++ and VisualAge C++ for OS/400 product folders each contain a
project template. The Tools setup of each template includes actions, environment var-
iables, and types specific to the target run-time environment:
Ÿ The VisualAge C++ Project Template contains a setup specific to OS/2 applica-
tion development
Ÿ The VisualAge C++ for OS/400 Project Template contains a setup specific to
OS/400 application development

Depending on the type of application you plan to develop, you might want to have
access to all tools for both platforms, from within a single project. To create a project
that inherits from both the VisualAge C++ Project Template and the VisualAge C++
for OS/400 Project Template, follow these steps:
1. Open the main VisualAge C++ for OS/400 folder, point to the VisualAge C++
for OS/400 Project Template icon, and press mouse button 2 to open a popup
menu.
2. Click on the arrow next to the menu item Create another, and select VisualAge
C++ for OS/400 Project Template.
3. In the Settings notebook that opens, highlight Desktop as the location for the
new project folder, and enter a name in the New Name entry field, for example
Client/Server.
4. Click on Create, to create the new project; a new icon labelled Client/Server
appears on the OS/2 Desktop.
5. Double-click on this icon to open the project.
6. Click on View on the menu bar, and select Settings to open the Settings note-
book.

30 IBM VisualAge C++ for OS/400 C++ User’s Guide


Adding an Action to a Project

7. Click on the Inheritance tab to get to the page where to specify the projects to
inherit from.
8. Click on Add, to open a dialog box. In the Open filename entry field, enter the
filename and location of the project to inherit from.
If you are not sure of the exact name, select the drive, directory, and sub-
directory that contains the project, and have the system fill the File entry field
with the project name.
9. Close the dialog box to update the Settings notebook with the name and path of
the project to inherit from, and close the Settings notebook.

The new Client/Server project now combines the actions, environment variables,
and object types of both the VisualAge C++ project template and the VisualAge C++
for OS/400 project template. To display actions and object types:
1. Double-click on the Client/Server project icon, to open the project folder
2. Click on Tools setup, to bring up a list of all actions available to project objects
3. Click on View and select Types, to bring up a view of all object types that can
be included in the project

Adding an Action to a Project's Tools setup


The project templates contain all the actions that are typically used to develop C++
applications on each platform. However, you may find it useful to add your own
actions to those already provided.

The following example shows how to create an action that connects your OS/2 work-
station to an AS/400, and how to add this action to an existing action class.

See the VisualAge C++ for OS/2 User’s Guide for a complete discussion of cre-
ating new actions and action classes.

Adding a Connect Action to the Run Action Class


Before you can compile C++ source files into OS/400 objects, you must establish a
connection between your OS/2 workstation and an AS/400.

Instead of establishing this connection from an OS/2 command line using the
CTTCONN command, you can add a Connect action to an existing action class of
your WorkFrame project.

To add a Connect action to the Run action class of the Client/Server project,
follow these steps:
1. Double-click on the Client/Server icon, to open the project

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 31


Adding an Action to a Project

2. Click on Tools setup, to bring up a list of all actions


3. Click mouse-button 2 on the Run action-class icon and select Add from the
popup menu, to bring up the Add Action notebook
4. Enter the following information in the entry fields:
Class Run
Name CONNECT
Program CTTCONN
5. Check the Project checkbox; the IWFBPAM Access method is automatically
specified
6. Click on OK and close the notebook
7. Double-click on the Run action class, to see the Connect action added to the list
of available actions

Customizing the Connect Action


The Connect action establishes a connection between an OS/2 workstation and an
AS/400 by invoking the CTTCONN command. This command requires command
parameters, or settings in environment variables, to establish a specific connection.
You can supply this information in one of two ways:
Ÿ Enter the parameters in the Parameters entry field of the Default Options note-
book that opens when you invoke the Connect action
Ÿ Customize the Connect action by adding environment variables to the project

The following steps add environment variables to the project:


1. Click on Variables in the Tools setup window of the Client/Server project, to
bring up the Add Environment Variable dialog box
2. Enter the following information in the entry fields:
Name ICCASHOST
String Partner LU alias of the target AS/400 system, for example MYAS1ðð
3. Click on Add
4. Click on Variables in the Tools setup window of the Client/Server project, to
bring up the Add Environment Variable dialog box for the next environment
variable
5. Enter the following information in the entry fields:
Name ICCASNAME
String User-defined connection name, for example MYCON1

32 IBM VisualAge C++ for OS/400 C++ User’s Guide


Adding an Action to a Project

6. Click on Add
7. Close the Tools setup window

See “Establishing an AS/400 Connection Before Compiling and Binding” on


page 40 for a description of the CTTCONN command, its syntax and parameters, and
the corresponding environment variables.

Chapter 3. Creating OS/400 C++ Applications with WorkFrame 33


Adding an Action to a Project

34 IBM VisualAge C++ for OS/400 C++ User’s Guide


Part 2. Compiling Your Program
The chapters in this part describe how to compile an OS/400 application with the C++
cooperative compiler that is part of VisualAge C++ for OS/400. Topics cover:
Ÿ Starting the C++ Cooperative Compiler
Ÿ Controlling Compiler Input
Ÿ Controlling Compiler Output
Ÿ Setting Compiler Options

 Copyright IBM Corp. 1995 35


36 IBM VisualAge C++ for OS/400 C++ User’s Guide
Compiling across Operating Systems

4 Starting the Compiler

IBM VisualAge C++ for OS/400 includes a cooperative compiler that lets you
compile OS/400 C++ applications from your OS/2 workstation, targeting an AS/400
system. It is simply called the compiler from here on.

This chapter briefly introduces the concept of cooperative compiling in the AS/400
Integrated Language Environment. It also explains how to establish a connection
between an OS/2 workstation and an AS/400, and how to invoke the compiler.
Topics include:
Ÿ Compiling across operating systems
Ÿ Establishing an AS/400 connection before compiling and binding
Ÿ Ending an AS/400 connection
Ÿ Invoking the compiler
Ÿ Determining compiler output
Ÿ Working with multiple compilers

If you are new to the AS/400, see ILE Concepts for more information about
modules and module creation in the Integrated Language Environment.

Compiling across Operating Systems


The compiler compiles C++ source code across two different operating systems:
Ÿ The compiler front end runs on your OS/2 workstation and generates an interme-
diate code file from each C++ source file. This intermediate code file is transpar-
ently transferred to an AS/400 system of your choice.
Ÿ The compiler back end finishes compilation of the intermediate code file on the
AS/400 system. There, it produces an OS/400 module object (\MODULE) for each
intermediate file. Module objects can be bound into program objects (\PGM) that
run in the Integrated Language Environment on the AS/400. Module objects can
also be bound into service program objects (\SRVPGM) to be called by ILE pro-
grams.

This approach lets you develop OS/400 C++ applications directly from an OS/2 work-
station, where you can use graphical user interface (GUI) tools. At the same time,
you take advantage of the AS/400's storage capacity, security, and data integrity.

Figure 8 on page 38 shows how the compiler compiles and binds source files across
the two different platforms.

 Copyright IBM Corp. 1995 37


Compiling across Operating Systems

C++ Souce File


(.cpp)

iccas

Intermediate Code File


(.qwo)
OS/2
Workstation

AS/400
system
C++ Module Object
(*MODULE)

Other ILE Module Objects


Existing Service Programs

CRTPGM CRTSRVPGM

ILE Program or Service


Program
(*PGM or *SRVPGM)

Figure 8. Compiling and Binding with the Cooperative Compiler

Communication between OS/2 Workstation and AS/400


To allow the entire compilation process to take place, you must start a communication
session between the OS/2 workstation and the AS/400 of your choice, prior to
invoking the compiler.

Compiling after having established a connection between an OS/2 workstation and an


AS/400 is called compiling in connected mode. You may also compile your code
without being connected to an AS/400. This is called compiling in disconnected
mode.

In disconnected mode, compilation ends with the creation of intermediate code files,
which remain located on the OS/2 workstation. This mode is useful when you cannot
log on to an AS/400 system, or when you want the compiler to perform a syntax
check only.

38 IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiling across Operating Systems

See “Compiling in Disconnected Mode” on page 54 for details on compiling


without an AS/400 connection.

Creating and Transferring Intermediate Code Files


Each source file filename.cpp is compiled into an intermediate code file
filename.qwo. This intermediate file is then transferred to the AS/400, where the
compiler back end processes it into a module object FILENAME. This module object
can be bound either into a program or into a service program object.
Note: If you want to compile source code into a module object only, and not bind it
into a program or a service program, specify the /C compiler option.

The transfer of files to the AS/400 and the program or service program creation
(depending on the compiler option chosen) happen automatically, provided you estab-
lished a connection between the OS/2 workstation and the AS/400 prior to invoking
the compiler.

If such a connection is not active, compilation ends after the creation of the interme-
diate file filename.qwo on your OS/2 workstation.

Processing Multiple Source Files


If you invoke the compiler with multiple source files, processing takes place as
follows:
Ÿ If an AS/400 connection has been established, the compilation of the second
source file does not start until a module object has been created for the first
source file. If you have specified the compiler option /Fw, the compilation of
the second source file does not start until the creation of the first intermediate
code file is complete.
Ÿ In disconnected mode, the second compilation starts after the successful creation
of the first intermediate code file.
Ÿ In case compilation of a source file does not complete successfully, the compiler
returns an error message. Subsequent files will not be compiled.

See “Determining Compiler Output” on page 53 for more information on com-


piling in connected or disconnected mode, and on creating intermediate code files
only.

Compiling Source Code into Module Objects


The compiler generates module objects from source files. An object of type \MODULE
is the basic building block of an ILE program or service program.

Chapter 4. Starting the Compiler 39


Establishing an AS/400 Connection

Contents of Module Objects


In ILE C++ or ILE C, a module may consist of one or more procedures (functions).
The module object includes a list of the imports and exports referenced within the
module. It may also include debug data, if this was requested at compile time,
through the choice of compile options.

Binding Module Objects


A module cannot be run by itself. Instead, one or more modules bound together
create a program object (type \PGM) that can be run. By default, invoking the com-
piler results in the creation of a program object. Alternatively, modules can be bound
to create service programs (type \SRVPGM).

See “Creating a Program Using iccas Defaults” on page 53 for information on


creating a program using default compiler settings. See Chapter 8, “Creating an
OS/400 Program” on page 127 and Chapter 9, “Creating a Service Program” on
page 141 for details on how to create programs and service programs from module
objects.

Advantages of Combining Module Objects


The ability to combine modules allows you to:
Ÿ Reuse pieces of code across applications.
Ÿ Maintain shared code with little chance of introducing errors to other parts of the
overall program.
Ÿ Manage large programs more effectively by dividing them into parts that you
write, test, and debug separately. If the program needs to be enhanced, you only
recompile those modules that have been changed.
Ÿ Create mixed-language programs, binding together modules written in the ILE
language that is most appropriate for the task required.

Establishing an AS/400 Connection Before Compiling and Binding


Before you can compile or bind an OS/400 C++ application from your OS/2 work-
station, you must first establish a connection with an AS/400, using the CTTCONN
command.
Note: Communication between an OS/2 workstation and an AS/400 requires the ser-
vices provided by Communications Manager. To start Communications Manager from
an OS/2 command line, type STARTCM. If you do not start Communications Manager,
you can still use the compiler, but compilation results in intermediate code files only.

40 IBM VisualAge C++ for OS/400 C++ User’s Guide


Establishing an AS/400 Connection

Setting up Host Server Sessions on the AS/400


The CTTCONN command starts a host server job on the AS/400 you are connecting
to.

By default, host server jobs on the AS/400 are reused. Therefore, you should start
with a clean QTEMP file and job log for your server session. Otherwise you cannot
ensure that you get a consistent start-up state.

Ask your system administrator to set the maximum number of prestart jobs
(MAXJOBS) that can be active at the same time for this prestart job entry to 1. The
corresponding AS/400 command is:
CHGPJE SBSD(QSYS/QCMN) PGM(QIWS/QSRCSRVR) MAXUSE(1)

Using the CTTCONN Command to Connect to an AS/400


You establish a connection between your OS/2 workstation and an AS/400 by issuing
the CTTCONN command from the command line in any OS/2 window that has the
environment settings for the compiler.
Note: You can invoke this command more than once, to establish more than one
connection at a time between your OS/2 workstation and one or several AS/400
systems.

The syntax for the CTTCONN command is:

55──CTTCONN──┬────────┬──┬──────────┬──────────────────────────5%
└─/Hname─┘ └─/ASnname─┘

The CTTCONN command takes two parameters to uniquely identify a connection


between an OS/2 workstation and an AS/400:
Ÿ /Hname
Ÿ /ASnname

You can enter ? as the first parameter to the CTTCONN command to display the
command syntax.

/Hname
This parameter identifies the AS/400 system you are connecting to. You can specify
/Hname in one of two ways:
Ÿ Specify the network ID of your AS/400, followed by a period (.), followed by its
partner LU name
Ÿ Specify the partner LU alias of your AS/400..

Chapter 4. Starting the Compiler 41


Establishing an AS/400 Connection

For example, specify /H as one of the following:


Ÿ /Homxnidas.toras444
Ÿ /Hrisc444

Instead of typing /Hname each time you invoke the CTTCONN command, you can
specify its value in the ICCASHOST environment variable, and omit /Hname when
invoking CTTCONN.

You can set the ICCASHOST environment variable permanently, in your


CONFIG.SYS file, or at the beginning of each OS/2 workstation session through the
command:
SET ICCASHOST=<partner LU>

For example, if the network ID of your AS/400 is OMXNIDAS, the partner LU name is
TORAS444, and the partner LU alias is RISC444, you can set ICCASHOST to one of
the following values:
Ÿ SET ICCASHOST=OMXNIDAS.TORAS444
Ÿ SET ICCASHOST=RISC444
Note: Since the value for ICCASHOST is always automatically set to uppercase
characters, you should not use lower case characters in your partner LU alias, to
avoid a mismatch.

You may have set up your system with the same value for both your partner LU
name and your partner LU alias. In this case, you can set ICCASHOST to one of the
following values:
Ÿ SET ICCASHOST=OMXNIDAS.TORAS444
Ÿ SET ICCASHOST=TORAS444

If you later want to override the setting in the ICCASHOST environment variable,
simply specify /Hname for your connection when you invoke the CTTCONN
command.

/ASnname
This parameter is a user-defined unique name for the connection. The name you
choose must be a string that does not exceed 10 alphanumeric characters.

Instead of typing /ASnname each time you invoke the CTTCONN command, you can
specify the connection name on the ICCASNAME environment variable, and omit
/ASnname when invoking CTTCONN.

42 IBM VisualAge C++ for OS/400 C++ User’s Guide


Establishing an AS/400 Connection

You can set the ICCASNAME environment variable permanently, in your


CONFIG.SYS file, or at the beginning of each OS/2 workstation session through the
command:
SET ICCASNAME=<name>

If you later want to override the setting in the ICCASNAME environment variable,
simply specify /ASnname for your connection when you invoke the CTTCONN
command.

Identifying an AS/400 System Through its Partner LU Name or Alias


Each AS/400 is identified either through its network ID and its partner logical unit
(LU) name, or through its partner LU alias, which are unique within your local
network. Use either of these values in the environment variable ICCASHOST, or on
the /Hname parameter of the CTTCONN command
Note: Any partner LU alias used must be identical to those specified when you set
up Client Access/400 Optimized for OS/2 Client.

Specifying a User-Defined AS/400 Connection Name


You define the name which uniquely identifies each AS/400 connection. A con-
nection name must be a string of one to ten alphanumeric characters.

Specify the connection name in one of two ways:


Ÿ In the environment variable ICCASNAME
Ÿ On the /ASnname parameter of the CTTCONN command

If ICCASNAME is set, the /ASnname parameter on the CTTCONN command is not


necessary. If /ASnname is used, it overrides the name specified by ICCASNAME. If
/ASnname is not specified and ICCASNAME is not set, an error results.
Note: Any process on the OS/2 workstation can use an AS/400 connection estab-
lished through CTTCONN. You must ensure that no two processes are using the
same connection concurrently, because this may produce undesirable results.

Establishing Multiple Connections Between an OS/2 Workstation and an AS/400


You can start connections with several different AS/400 systems, or you can start
several connections with the same AS/400. You must establish each connection sepa-
rately through the CTTCONN command.

For example, the command CTTCONN /Hhost1 /ASnserver1 establishes an AS/400


connection called server1 with the AS/400 host1.

The command CTTCONN /Hhost1 /ASnserver2 establishes a second connection


called server2 with the same AS/400:

Chapter 4. Starting the Compiler 43


Establishing an AS/400 Connection

The command CTTCONN /Hhost2 /ASnserver3 establishes a third connection


called server3 with a second AS/400, host2:

Special Considerations When Working with Multiple Connections


When working with multiple connections between your OS/2 workstation and one or
more AS/400 systems, keep the following points in mind:
Ÿ Connection names must be unique. You cannot use the same connection name
for two connections, even if you are connecting to two different AS/400 systems.
Ÿ If you run multiple connections in the same OS/2 window, you can use the envi-
ronment variable ICCASNAME only once. For all other connections, you must
override ICCASNAME with /ASnname.
The same is true for the environment variable ICCASHOST, if you are con-
necting to several AS/400 systems. You must set it for each connection.
Ÿ To avoid conflicts in case of multiple connections, you can run each connection
in its own OS/2 window. In this case, you can set the environment variables
ICCASHOST and ICCASNAME for each window, independently.
Note: Environment variables set in CONFIG.SYS are in effect for all OS/2
windows, unless you override them by using the SET command, or by using the
parameters /Hname and /ASnname.

Querying Existing Connections through CTTQCONN


To find out which connections are currently active, use the CTTQCONN command.
The syntax for this command is:

55──CTTQCONN───────────────────────────────────────────────────5%

The CTTQCONN command does not take any parameters.

When you type CTTQCONN in an OS/2 window that has the environment settings for
the compiler, a list of all currently established connections is displayed.

Use this command to display connection names already in use, or to check on the
status of a particular connection.
Note: A connection either exists or does not exist. If there is an error in the com-
munication between the OS/2 workstation and the AS/400, the connection goes down.
It does not remain in a state of error.

44 IBM VisualAge C++ for OS/400 C++ User’s Guide


Establishing an AS/400 Connection

Issuing AS/400 CL Commands from the OS/2 Workstation


When you have established an AS/400 connection through CTTCONN, you can issue
AS/400 CL commands from your OS/2 workstation through this connection, using the
CTTHCMD command. Generally, any commands that can be run in batch mode can
be run through the CTTHCMD command.

The syntax for the CTTHCMD command is:

55──CTTHCMD──┬──────────┬──┬────┬──┬──────────────┬────────────5%
└─/ASnname─┘ └─/Q─┘ └─as4ððcommand─┘

or

55──CTTHCMD──@response_file────────────────────────────────────5%

The CTTHCMD command takes the following parameters:

/ASnname
The /ASnname parameter is a user-defined name for the connection that you can use
to issue an AS/400 CL command.

See “Using the CTTCONN Command to Connect to an AS/400” on page 41 for


a description of ASnname.

/Q
The Q parameter suppresses informational messages. It is an optional parameter.

as400command
The as4ððcommand parameter represents the AS/400 CL command you want to issue
from your OS/2 workstation. for CTTHCMD command

?
You can enter ? as the first parameter to the CTTHCMD command to display the
command syntax.

How to Use the CTTHCMD Command


You can use this command for example to change the current library list on the
AS/400, add library list entries, or create programs and service programs, interactively
or in batch mode.

Chapter 4. Starting the Compiler 45


Establishing an AS/400 Connection

Note: The position of /ASnname and /Q can be interchanged, but both must appear
before the AS/400 command. The AS/400 command will be parsed as is, without
escape sequence processing.

For example, the command:


CTTHCMD /ASnmyserver CHGCURLIB MYLIB

changes the current library on the AS/400 implied by the connection name myserver
to MYLIB.

Alternatively, if the AS/400 command is too long to be placed conveniently on the


OS/2 command line, the entire argument list to CTTHCMD may be put into a
response file. In this case, the @filename argument can be used. The syntax is:
CTTHCMD @filename

The atsign (@) must precede the filename.


Note: An AS/400 command that is split into lines in the file is separated by at least
one blank. For example,
crtpgm abc actgrp(ag
one)

is processed as
crtpgm abc actgrp(ag one)

Example of Issuing an AS/400 Command from an OS/2 Workstation


The following command file is intended to create a program so that it can run on the
AS/400 system MYSYS001.

'set iccasname=os4ðða'
'set iccashost=mysysðð1'
'cttconn'
'ctthcmd chgcurlib testlib'
'ctthcmd crtpgm \curlib/gf module(gf) '
'ctthcmd call testylib/gf'
'ctthcmd dltpgm testlib/gf'
'cttdis'

If the CTTHCMD command fails on the AS/400, an AS/400 error code and message
are displayed on the OS/2 workstation, unless you have used the /Q option.
Note: From the OS/2 workstation, you cannot access the message prompts or help
provided on the AS/400.

46 IBM VisualAge C++ for OS/400 C++ User’s Guide


Ending an AS/400 Connection

Renaming the CTTHCMD Command


You can rename or copy the CTTHCMD.EXE file to a different name. In this case,
when invoked, the command behaves differently. The /ASnname and /Q parameters,
or the @filename argument are no longer recognized.

The AS/400 command issued is the new name of the .EXE file appended with the
argument, as shown in the following example, where CTTHCMD.EXE is copied to
CRTPGM.EXE:

The command
CRTPGM A MODULE(A B)

issued from the OS/2 workstation sends the command


CRTPGM A MODULE(A B)

to the AS/400.
Note: If you want to use command names longer than eight characters, such as
CHGCURLIB.EXE, the command must reside on a file system that accepts filenames
that are longer than eight characters, such as the High Performance File System
(HPFS).

Attention: If you decide to copy or rename the CTTHCMD command, you must
update these copies if a new version of CTTHCMD is released. Failing to do so may
result in an executable not working properly with the new version.

Ending an AS/400 Connection


When you no longer require the connection(s) that you have established through the
CTTCONN command, you must either disconnect from the AS/400 system(s), or end
all connections.

The commands you can use are CTTEND and CTTDIS. You can enter ? as the first
parameter to both commands to display the command syntax.

The following differences exist between the CTTEND and CTTDIS commands:

Using the CTTEND Command


CTTEND affects all connections. The syntax for the command is:

55──CTTEND─────────────────────────────────────────────────────5%

Chapter 4. Starting the Compiler 47


Invoking the Compiler

This command does not take any parameters. Type CTTEND on an OS/2 command
line to end all connections between your OS/2 workstation and any AS/400 system
that you have established through the CTTCONN command.

In addition to disconnecting your OS/2 workstation from all AS/400 systems,


CTTEND also takes down the Presentation Manager window associated with the con-
nections.

Using the CTTDIS Command


CTTDIS affects a single connection, and does not take down the Presentation
Manager window associated with the existing connections.

The syntax for the command is:

55──CTTDIS──/ASnname───────────────────────────────────────────5%

The parameter ASnname is required, unless you have set the ICCASNAME environ-
ment variable. /ASnname specifies the name of the connection you wish to discon-
nect. Type:
CTTDIS /ASnname

on the OS/2 command line to disconnect only the AS/400 connection identified by
the /ASnname parameter. The command does not disconnect any other connections
that may be active.

CTTDIS does not take down the Presentation Manager window associated with the
connection to the AS/400.

Use CTTDIS if you want to selectively disconnect one of a number of active con-
nections. If you only have a single connection, use CTTDIS followed by CTTEND.

Recovering from an OS/2 Workstation Reboot


In case you need to reboot your OS/2 workstation while connected to an AS/400, the
AS/400 job associated with your connection remains active.

You must terminate the AS/400 connection explicitly through the Work With Active
Jobs (WRKACTJOB) command, from an AS/400 session.

Invoking the Compiler


The iccas command invokes the compiler, which takes C++ source code as input and
produces an intermediate code file, a preprocessed file, or a module object, according

48 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking the Compiler

to the compiler options specified. The command also invokes the AS/400 binder to
bind the module object into a program or a service program object.

You can issue the iccas command in the following ways:


Ÿ Invoke the compiler from WorkFrame, if you prefer working with interactive
compiler option dialogues
Ÿ Invoke the compiler from a make file, if you need to compile multiple files that
depend on each other.
Ÿ Invoke iccas from an OS/2 command line, like any other OS/2 program
Ÿ Invoke iccas from a response file, if you need to compile multiple files that
depend on each other.
Ÿ Use the system function, if you want to invoke the compiler from within another
program.
For example, insert the statement system("iccas myfile.cpp"); in any other C
or C++ program.
Note: In any case, do not forget to establish communication between your OS/2
workstation and an AS/400 prior to invoking the compiler, if you want the compila-
tion to result in the creation of a \MODULE object on the AS/400. See “Estab-
lishing an AS/400 Connection Before Compiling and Binding” on page 40 for details
on establishing communication between your OS/2 workstation and an AS/400.

Compiling from within WorkFrame


You can invoke the compiler from any WorkFrame project through the Compile
action.

See “Compiling Source Files” on page 22 for details on how to set compiler
options and invoke the compiler from a WorkFrame project.

Compiling from a Make File


When your application comprises a number of source files, use a make file to
organize the sequence of actions (such as compiling and binding) required to build
your project. You can then invoke all the actions in one step. This approach saves
you time by performing actions on only the files that have changed, and on the files
that incorporate or depend on the changed files.

You can write the make file yourself, or you can use the WorkFrame utility MakeMake
to write the make file for you. For more information on the MakeMake utility do the
following:
1. Open the WorkFrame folder

Chapter 4. Starting the Compiler 49


Invoking the Compiler

2. Open the Tools folder, in the WorkFrame folder


3. Double click on the MakeMake icon The MakeMake window appears
4. Select Help->General help

See Chapter 11, “Creating a Make File” on page 171 for details on writing your
own make file.

Compiling from the OS/2 Command Line


The syntax for the iccas compiler invocation command is as follows:

55──iccas──┬─@response_file───────────────────────────┬────────────────────────5%
│ ┌──
──────────────────────────────────────┐ │
│ │ ┌──
───────────┐ │ │
└────6┬─────────┬┴──┬───────────────────┬─┴─┘
6
└─/option─┘ ├─source────────────┤
└─intermediate_file─┘

Depending on how you want to compile your files and how you have set up your
environment variables many of the parameters used with the iccas command are
optional when you issue the command from an OS/2 command line. See “OS/2
Environment Variables for Compiling” on page 62 for information on ICCAS and
other environment variables.

For example, to compile the program myprog.cpp, you enter the following command
on an OS/2 command line:
iccas myprog.cpp

An intermediate code file, myprog.qwo, is created on OS/2, and, if an AS/400 con-


nection has been established, by default, a program object MYPROG is created on the
AS/400.

Displaying a Compiler Option Listing


To see an online list of all the compiler options type at the OS/2 command line:
iccas /?
Note: The listing generated by this command is not intended to be used as a pro-
gramming interface.

The listing is printed to your OS/2 workstation display, but you can use the OS/2
redirection symbols to redirect it to a file:
iccas /? 2> mylist

This command redirects the file handle 2 (stderr) to mylist.

50 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking the Compiler

See Chapter 7, “Setting Compiler Options” on page 89 for a detailed description


of all compiler options.

Compiling Files Without a File Extension


When you invoke the compiler without specifying a file extension, for example by
typing iccas abc on an OS/2 command line, the compiler assumes that you do not
want to compile the source file abc.cpp, but want to call the binding step alone to
create a \PGM or a \SRVPGM object on your AS/400.

The compiler searches for the appropriate module object ABC and issues an error
message if this module does not exist in the search path. Make sure you specify the
appropriate file extension when you want to compile a source code file.
Note: If you do not specify a library name, the compiler searches the current library.
If there is no current library, or if the search has not been successful, the compiler
searches the QGPL library.

Consider the following invocation cases:


Ÿ The command iccas abc results in the binder invocation CRTPGM PGM(ABC)
MODULE(ABC).
Ÿ The command iccas /b"crtsrvpgm abc" abc results in the binder invocation
CRTSRVPGM SRVPGM(ABC) MODULE(ABC).
Ÿ The command iccas /b"crtpgm abc actgrp(xyz)" abc def results in the
binder invocation CRTPGM PGM(ABC) ACTGRP(XYZ) MODULE(ABC DEF).
Note: In the examples, above, the compiler queries the AS/400 for the name of the
current library. If there is none, or if the query is not successful, the library defaults
to QGPL. You can also specify a library name on the /ASl compiler option.

See “Specifying Compiler Options” on page 89 for a complete list of compiler


options.

Compiling Multiple Source Files into Modules


To compile programs that use more than one source file, specify all the file names on
the OS/2 command line. For example, to compile a program with three source files,
mainprog.cpp, subs1.cpp, and subs2.cpp, type:
iccas mainprog.cpp subs1.cpp subs2.cpp

The compiler creates three module objects, MAINPROG, SUBS1, and SUBS2, on the
AS/400 you are connected to, as well as one program object MAINPROG.

Chapter 4. Starting the Compiler 51


Invoking the Compiler

In case the compilation of one source file into a module object \MODULE fails, the
compiler will not attempt to compile the remaining source files, and a program object
is not created.
Note: If you want to create a separate program object for each source file, you must
compile each source file separately.

For example, to compile the three source files, mainprog.cpp, subs1.cpp, and
subs2.cpp, into three separate program objects, type:
iccas mainprog.cpp
iccas subs1.cpp
iccas subs2.cpp

Each successful compilation creates one module object, and one program object.

Compiling C Source Files With the C++ Compiler


C source files are compiled as C++ files. They may not compile correctly without
source code modifications to follow C++ syntax and semantics.

For example, the command iccas cprog.c is interpreted by the compiler as iccas
cprog.cpp.

See the VisualAge C++ for OS/400 C++ Programming Guide for information on
how to prepare C source code for compilation with the cooperative compiler, and for
a discussion of portability considerations.

Invoking the Compiler Using A Response File


Instead of specifying source files and compiler options on the OS/2 command line,
you can use a response file. A response file is a text file that contains a string of
options and file names to be passed to iccas. (The string does not specify iccas
itself.) For example, the response file:
/Sa /Fl inventory.cpp
would give the following OS/2 command line:
iccas /Sa /Fl inventory.cpp

A response file can have any valid OS/2 file name and extension. To use the
response file, specify it with the iccas compiler invocation on an OS/2 command line
preceded by the atsign (@). For example:
iccas @d:\response.fil

No space can appear between the atsign (@) and the file name. You can use multiple
response files, and even nest response files within a response file.

52 IBM VisualAge C++ for OS/400 C++ User’s Guide


Determining Compiler Output

You can specify response files in addition to other input on the OS/2 command line.
In this case, the compiler will evaluate all options and file names specified in the
response file, on the OS/2 command line and in the ICCAS environment variable.

The command string in a response file can span multiple lines. No continuation char-
acter is required. The string can also be longer than the limit imposed by the OS/2
command line.

In some situations you may need to use a response file to accommodate a long OS/2
command, such as when you compile C++ code containing templates.
Note: Because the compiler appends a space to the end of each line in the response
file, be careful where you end a line. If you end a line in the middle of an option or
file name, the compiler does not interpret the file as you intended. For example,
given the following response file:
/Sa /F
l inventory.cpp
the compiler constructs the command iccas /Sa /F l inventory.cpp The compiler
then generates an error message that the /F option is not valid, and tries to compile
and create program objects from the files l.qwo and inventory.cpp.

Determining Compiler Output


The compiler can produce several types of output. Depending on the nature of your
project, and your stage in the development process, you may want to:
Ÿ Create a program using iccas defaults
Ÿ Create a program using specific compiler options
Ÿ Compile in connected mode
Ÿ Compile in disconnected mode
Ÿ Create an intermediate code file

Creating a Program Using iccas Defaults


To compile your program with the iccas default settings, simply invoke the compiler
without specifying any compiler options. (This assumes that you have also not speci-
fied any options in the ICCAS environment variable.)

In the example invocation iccas test.cpp, the source file test.cpp located in your
current directory on your OS/2 workstation is compiled into a module object named
TEST and a program object named TEST, both located in your current library on the
AS/400.

Chapter 4. Starting the Compiler 53


Determining Compiler Output

Creating a Program Using Specific Compiler Options


To override default compiler options, simply specify the options you wish to use
when you invoke the iccas command. For example, the command
iccas /b"crtsrvpgm srvpgm(mylib/myserv)" myfile.cpp

results in source file myfile.cpp being compiled into a module object MYFILE and
bound into a service program MYSERV in library MYLIB, on the AS/400.

See Chapter 7, “Setting Compiler Options” on page 89 for a complete list of


compiler options and their default settings.

Compiling in Connected Mode


Compiling in connected mode means that a connection has been established between
your OS/2 workstation and an AS/400, before you invoke the compiler.

This connection needs to be established only once, at the beginning of your compile
session. See “Establishing an AS/400 Connection Before Compiling and
Binding” on page 40 for the exact steps required to connect your OS/2 workstation to
an AS/400.

When you invoke the compiler in connected mode, the invocation command iccas
creates one intermediate code file for each C++ source file, and transfers it for you to
the AS/400. There, for each intermediate code file, a module object is created, which
may be bound into either a program or a service program, depending on the compiler
options you have specified.

In the following example, it is assumed that you have established a connection


between your OS/2 workstation and an AS/400, through the CTTCONN command.

The compiler invocation iccas /b"crtpgm pgm(mylib/myprog)" myfile.cpp


results in source file myfile.cpp being compiled on the OS/2 workstation into an
intermediate code file myfile.qwo which is transferred to the AS/400, where a
module object MYFILE is created. This module object is bound into a program object
MYPROG in library MYLIB.

Compiling in Disconnected Mode


Compiling in disconnected mode means that a connection has not been established
between your OS/2 workstation and an AS/400, before you invoke the compiler.

If you cannot, or choose not to, establish a connection with an AS/400 you can still
invoke the compiler. In this case, the compilation process takes place on the OS/2
workstation only, and, by default, ends with the creation of an intermediate code file

54 IBM VisualAge C++ for OS/400 C++ User’s Guide


Determining Compiler Output

for each C++ source file. The intermediate file is not transferred to an AS/400 system
because there is no established connection.

Benefits of Compiling in Disconnected Mode


Compiling in disconnected mode allows you to syntax check your code. In this case,
before you can further process the resulting intermediate code files into OS/400 pro-
grams or service programs, you must connect your OS/2 workstation to an AS/400.

If this is not possible, you must copy the intermediate code files to an OS/2 work-
station that is connected to an AS/400 Then you invoke the compiler specifying the
names of the intermediate code files, which will normally result in the creation of
\MODULE and \PGM objects, depending on the compiler options you choose.
Note: In disconnected mode, externally described files located on AS/400 are
normally not accessible to the compiler. An exception are header files that you have
previously created on your OS/2 workstation through the #pragma mapinc directive.

See the VisualAge C++ for OS/400 C++ Programming Guide for details on using
#pragma mapinc.

Examples of Compiling in Disconnected Mode


In the following examples, it is assumed that you have not established a connection
between your OS/2 workstation and an AS/400, through the CTTCONN command.

The compiler invocation iccas myfile.cpp simply results in the creation of an inter-
mediate code file myfile.qwo on your OS/2 workstation.

This intermediate code file is not transferred to the AS/400, because a connection has
not been established prior to invoking the compiler.

The command iccas /b"crtpgm pgm(mylib/myprog)" myfile.cpp also results in


source file myfile.cpp being compiled on the OS/2 workstation into an intermediate
code file myfile.qwo. However, compilation halts here, because the intermediate
code file cannot be transferred to an AS/400. The corresponding module and
program objects cannot be created.

Creating an Intermediate Code File Only


You may not always want to fully compile source files into module objects and bind
them into programs or service programs. If this is the case, you have the possibility
to compile C++ source files into intermediate code files only, which remain on your
OS/2 workstation until you process them further.

When you later want to create a module object from an intermediate code file, you
specify the name of the intermediate code file on the compiler invocation command.

Chapter 4. Starting the Compiler 55


Determining Compiler Output

For example, if you have previously compiled a file hello.cpp into an intermediate
code file hello.qwo, the compiler invocation
iccas hello.qwo
results, in connected mode, in the transfer of this intermediate code file to the
AS/400. There, a module object HELLO and, by default, a program object HELLO are
created.

There are several ways to perform a compile such that only an intermediate code file
is created.
Ÿ Specify /Fw+ or /Fw[name], which results in the creation of an intermediate file
that is saved for subsequent processing. The compiler does not attempt to create
a module object from the intermediate code file.
The compiler invocation iccas /FwC:\mydir\hello myfile.cpp results in the
creation of the intermediate code file hello.qwo from the C++ source file
myfile.cpp. hello.qwo is located in directory mydir on drive C:
The /Fw option in conjunction with the /Asd option may be useful when you
want to be able to work in disconnected mode on a file that needs to retrieve
large amounts of information from AS/400.
In this case, create a file that contains all the #pragma mapinc directives you
need to use, as well as their corresponding #include statements, and compile it
in connected mode with the /Fw+ /Asd options. This ensures that all temporary
files are located on OS/2, and are available when you later compile in discon-
nected mode.
See VisualAge C++ for OS/400 C++ Programming Guide for a detailed dis-
cussion of using #pragma mapinc with externally described files.
Ÿ Do not establish a connection to an AS/400. Your source file will be compiled
into an intermediate file, but the transfer of this intermediate file to the AS/400
will fail.
The compiler invocation
iccas myfile.cpp
results in the creation of the intermediate code file myfile.qwo from the C++
source file myfile.cpp.
The compiler invocation
iccas file1.cpp file2.cpp file3.cpp
results in the creation of the intermediate code file file1.qwo from the C++
source file file1.cpp.

56 IBM VisualAge C++ for OS/400 C++ User’s Guide


Working With Multiple Compilers

Note: In the example above, the compiler does not attempt to compile the sub-
sequent source files file2.cpp and file3.cpp, because the creation of a module
object for file1.cpp failed.
Ÿ If you do not need an intermediate code file for further processing, you can gain
time by specifying the compiler option /Fc which results in syntax check only.
In this case, the compiler does not attempt to create an intermediate file, nor a
module and a program object.
The compiler invocation
iccas /Fc myfile.cpp
results in the creation of a listing file myfile.lst only.

Working With Multiple Compilers


VisualAge C++ for OS/400 contains compilers that target the following run-time
environments:
Ÿ OS/2 workstation
Ÿ OS/400 V3R6 RISC system
Ÿ OS/400 V3R1 IMPI system

The header files used for each target are located in different directories on your OS/2
workstation. To ensure that the compilers use the appropriate set of header files in
each case, three environment variables are set in your CONFIG.SYS file when you
install VisualAge C++ for OS/400:
Ÿ INCLUDE
Ÿ INCLUDE_ASV3R6
Ÿ INCLUDE_ASV3R1

Using the INCLUDE Environment Variable


If you have used the defaults provided by the installation utility, your CONFIG.SYS
file contains the following value for the INCLUDE environment variable:
C:\CSETPP\INCLUDE\MIH;C:\CSETPP\IBMCLASS

The INCLUDE environment variable is used when you compile source code for the
OS/2 platform through the icc compiler invocation command.

Using the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 Environment Variables


When you install VisualAge C++ for OS/400, the following values are added to your
CONFIG.SYS file:
Ÿ INCLUDE_ASV3R6=
Ÿ INCLUDE_ASV3R1=

Chapter 4. Starting the Compiler 57


Working With Multiple Compilers

The INCLUDE_ASV3R6 environment variable is used when you compile source code for
the AS/400 V3R6 RISC environment. The compiler uses the path specified in the
INCLUDE_ASV3R6 environment variable when you invoke the iccas command with
the default option /ASv3R1-.

The INCLUDE_ASV3R1 environment variable is used when you compile source code for
the AS/400 V3R1 IMPI environment. The compiler uses the path specified in the
INCLUDE_ASV3R1 environment variable when you specify the option /ASv3R1+ on the
iccas compiler invocation command.

58 IBM VisualAge C++ for OS/400 C++ User’s Guide


File Naming Conventions

5 Controlling Compiler Input

Depending on the size and nature of your project, you may want to vary, or cus-
tomize, the way you invoke the compiler and select compiler options. Topics in this
chapter include:
Ÿ File naming conventions for OS/2 and OS/400
Ÿ OS/2 environment variables you can set for compiling
Ÿ #include search paths and how to control them
Ÿ Source code language levels to choose from
Ÿ Compile-time limits for the C++ cooperative compiler

File Naming Conventions


When working with VisualAge C++ for OS/400, you must follow the file naming
conventions for both OS/2 and OS/400.

OS/2
The File Allocation Table (FAT) file system supports file names from one to eight
characters in length, optionally followed by a file name extension consisting of a
period (.) and one to three characters.

The High Performance (HPFS) file system supports long file names of up to 255
characters.

OS/400
Names can be entered in quoted or unquoted form. If you use the unquoted form,
every OS/400 file name can be 10 characters long and must begin with the characters
A-Z, $, #, or @. The remaining characters can also include numbers 0-9, underscores
( _ ), and periods (.).

Lower case letters (a-z) are changed to uppercase letters (A-Z) by the AS/400 system.
File names used in IBM-supplied AS/400 commands can be no longer than 10 char-
acters. Examples of file names are shown below:
[email protected]# ONE_NAME LIBRARY_ð6 $LIBX

If you use the quoted form \NAME (File Name in Quoted Form), the following
rules and considerations also apply:
Ÿ Every quoted name must begin and end with a double quotation mark (").

 Copyright IBM Corp. 1995 59


File Naming Conventions

Ÿ The middle characters of a quoted name can contain any character except asterisk
(\), question mark (?), single quote ('), double quote ("), hex 00 through 3F, or
hex FF.
Ÿ Graphic characters can be used
Ÿ The quoted form of file names used in IBM-supplied commands can be no longer
than eight characters (not including the double quotes).
Ÿ If a name enclosed in quotation marks is a valid unquoted basic name, the quota-
tion marks are removed. Thus, "ABC" is equivalent to ABC. Because the quota-
tion marks are removed, they are not included in the length of the name. "
ABCDEFGHIJ " is, therefore, a valid name even though it is longer than 10 char-
acters.

The following are examples of valid quoted names:


"A" "AA%abc" "ABC%%abc"

Using Wild Cards in File Names


You can use wild cards (\ or ?) in the name for any input file.

For example, the command iccas module?.cpp compiles all source code files that
have the extension .cpp and begin with module plus one additional character, such as
module1.cpp or module2.cpp. The resulting intermediate code files, modules and
program objects are given names derived from the source file, such as module1.qwo
and MODULE1.

The command iccas my\.cpp compiles all source files that have the .cpp file exten-
sion and begin with my, plus none, one, or several additional characters, such as
myfile and myprog.

You cannot use wild cards in the name for an output file. Either accept the default
output filenames, or specify an output filename in full.

Reserved Names
Do not give your user-defined functions names that are identical to the name of any
library function or external variable defined in the library. Otherwise conflicts
between user-defined identifiers (variable names or functions) and C library functions
may result.

Do not use an underscore (_) at the start of any of your external names. These iden-
tifiers are reserved for use by the compiler and libraries. All internal C++ identifier
names begin with an underscore (_), unless they are listed in this or in one of the
following manuals:
Ÿ VisualAge C++ for OS/400 C++ Language Reference

60 IBM VisualAge C++ for OS/400 C++ User’s Guide


File Naming Conventions

Ÿ VisualAge C++ for OS/400 IBM Open Class Library and IBM Access Class
Library for OS/400 Reference
Ÿ VisualAge C++ for OS/400 IBM Open Class Library and IBM Access Class
Library for OS/400 User’s Guide

If you have an application that uses a restricted name as an identifier, change your
code or use a macro to globally redefine the name and avoid conflicts. You can also
use the #pragma map directive to convert the name, but this directive may not be
portable.

Input File Types


The compiler uses file extensions to distinguish between the different types of files it
uses for input. The input file types are:
.h C++ header file
.i preprocessed file
.cpp C++ source file
.cxx C++ source file
.qwo intermediate code file

iccas compiles all input files as C++ files, except for those with an extension of
.qwo. These are intermediate code files resulting from an earlier compiler invocation
during which you could not, or chose not to, process them further into module and
program or service program objects.

When you specify intermediate code files on the compiler invocation command, they
are not compiled again on your OS/2 workstation, but are sent directly to the AS/400
to create module and program or service program objects.
Note: When intermediate code files are specified on the compiler invocation
command, they are not deleted from the OS/2 workstation after module and program
or service program objects are created on the AS/400.

When you specify C++ source files and intermediate code files on the same compiler
invocation, no additional processing is performed on the intermediate code files which
are sent directly to the AS/400 as is and which cannot incorporate any additional
compiler options specified with the current iccas invocation.

For example, to create a program from two source files (mainprog.cpp and
file2.cpp) and one intermediate code file (file3.qwo), type:
iccas /Fb mainprog.cpp file2.cpp file3.qwo

Chapter 5. Controlling Compiler Input 61


OS/2 Environment Variables for Compiling

The compiler creates two intermediate code files mainprog.qwo and file2.qwo.
These files, as well as the intermediate code file file3.qwo are transferred to the
AS/400, where three module objects MAINPROG, FILE2, and FILE3 are created and are
bound into a program object MAINPROG.

After the successful creation of program MAINPROG on the AS/400, the intermediate
code files mainprog.qwo and file2.qwo are deleted from the OS/2 workstation,
while the intermediate code file file3.qwo is not deleted, because it resulted from.
an earlier compiler invocation.

The /Fb option results in the creation of two browser listing files for mainprog.cpp
and file2.cpp. For file3.qwo a browser listing file is not created,

OS/2 Environment Variables for Compiling


The compiler makes use of the OS/2 environment variables to provide path informa-
tion and default values for compiler options. If the IBM VisualAge C++ for OS/400
installation program updated your CONFIG.SYS file, many of the environment vari-
ables were set to default values for the compiler. If the program did not update
CONFIG.SYS, you can set these values by running the CTTASENV.CMD file in your
OS/2 session before using the compiler.

Some environment variables, for example ICCAS are optional. They are not added to
your CONFIG.SYS file or to CTTASENV.CMD.

The environment variables described in this section are called the compiler environ-
ment variables.

The following OS/2 environment variables affect the operation of the compiler during
compilation:
PATH
The compiler searches for executable modules in the directories specified by
this variable.
DPATH
The compiler searches for help and message files in the directories specified by
this variable.
SAVEPATH
Use this variable to save a path you want to restore later.
You can easily add to the PATH variable, but it is not as easy to restore it
later. To avoid very long PATH statements in a command file, use a sequence
of commands similar to the following example:
SET SAVEPATH=%PATH% SET PATH=C:\CTTAS\BIN;%PATH%;

62 IBM VisualAge C++ for OS/400 C++ User’s Guide


OS/2 Environment Variables for Compiling

and restore the original path later with the following command:
SET PATH=%SAVEPATH%
INCLUDE_ASV3R1
The compiler searches for the system or user header files in the directories
listed by this variable. This environment variable is used when you compile
source files with the compiler option /ASv3r1 to target an AS/400 V3R1 run-
time environment.
INCLUDE_ASV3R6
The compiler searches for the system or user header files in the directories
listed by this variable. This environment variable is used when you compile
source files with the default compiler option /ASv3r1- to target an AS/400
V3R6 run-time environment.
TMP
This variable contains the path where the compiler places all its temporary
work files. If this variable is undefined, the compiler uses the current directory.
If you installed the compiler on a LAN, temporary files are stored in your local
directory. The work files created by the compiler are normally erased at the
end of compilation; however, if an interruption occurs during compiling, these
work files may still exist after the compilation ends. If you set the TMP vari-
able, you eliminate the possibility of work files being scattered around your file
system.
Setting TMP to point to a virtual disk (also called a RAM disk) may improve
compilation time. See the OS/2 documentation for information on using the
VDISK device driver to create a virtual disk. (Click on the Master Help Index
icon on your OS/2 desktop. Then search for the topic VDISK.)
ICCAS
You can use this variable to specify default compiler options as well as source
file names. See “Specifying Compiler Options” on page 89 for a more
detailed description of the ICCAS environment variable.
ICCASCP
You can use this variable to specify the coded character set identifier (CCSID)
of your target AS/400. The value that you specify is the CCSID that is
normally used for jobs running in your AS/400 environment.
See VisualAge C++ for OS/400 Read Me First! for a more detailed
description of the ICCASCP environment variable.
ICCASHOST
The compiler enables you to extract field descriptions from files located on an
AS/400, or create *MODULE and *PGM objects on an AS/400. However,
each compile session can only access one particular AS/400. You can use the

Chapter 5. Controlling Compiler Input 63


OS/2 Environment Variables for Compiling

ICCASHOST environment variable to specify the LU Alias of the AS/400 you


want to connect to.
The name on ICCASHOST must be identical to the one you specify as the host
server name on the CTTCONN command. You can override the ICCASHOST
environment variable by specifying the /H compiler option.
See “Establishing an AS/400 Connection Before Compiling and Binding”
on page 40 for a description of using ICCASHOST with the CTTCONN
command.
ICCASNAME
ICCASNAME is a user-defined alphanumeric string of a maximum of 10 char-
acters. You can use this environment variable to specify the name of a con-
nection to the AS/400 you want to connect to. The compiler uses this
information as input to the CTTCONN command when you connect to an
AS/400 system. You can override the ICCASNAME environment variable by
specifying the /ASn compiler option.
For example, if you want to identify your AS/400 connection from an AS/400
to the OS/2 workstation by the name connabc, you can set the environment
variable ICCASNAME to connabc before starting the compile session. The
default value for ICCASNAME is con1.
See “Establishing an AS/400 Connection Before Compiling and Binding”
on page 40 for a description of using ICCASNAME with the CTTCONN
command.

Setting Environment Variables


The OS/2 SET command lets you specify values for all environment variables. With
the exception of LIBPATH and DEVICE which must be set in CONFIG.SYS, you
can use the SET command in three places:
CONFIG.SYS file
Add a line that sets the environment variable to the value you want. For
example, type SET TMP=C:\ICCAS\TMP on an OS/2 command line.
If the environment variable already exists in CONFIG.SYS, add the VisualAge
C++ for OS/400 values to the existing variable. You can also have the
VisualAge C++ for OS/400 installation utility update CONFIG.SYS for you.
Environment variables specified in CONFIG.SYS are in effect for every session
you start. Therefore, CONFIG.SYS is a good place to specify variables that
you want to apply each time you compile, such as ICCAS, INCLUDE_ASV3R6, or
INCLUDE_ASV3R1.

64 IBM VisualAge C++ for OS/400 C++ User’s Guide


OS/2 Environment Variables for Compiling

CTTASENV.CMD file
The VisualAge C++ for OS/400 installation program creates this OS/2
command file. You must invoke this file in each session where you will use
the compiler. The variables set by CTTASENV.CMD are in effect only for the
session, or sessions, in which it is invoked.
If the installation program updated your CONFIG.SYS, CTTASENV.CMD con-
tains commands to set the TMP variable only. If the installation did not update
CONFIG.SYS, CTTASENV.CMD contains the following statements:
SET PATH=C:\CTTAS\BIN;%PATH%
SET DPATH=C:\CTTAS\DLL;%DPATH%
SET INCLUDE_ASV3R1=C:\CTTAS\INCLUDE\V3R1Mð;C:\CTTAS\INCLUDE\V3R1Mð\SYS;
E:\CTTAS\IBMCLASS;%INCLUDE%
SET INCLUDE_ASV3R6=C:\CTTAS\INCLUDE\V3R6Mð;C:\CTTAS\INCLUDE\V3R6Mð\MIH;
C:\CTTAS\INCLUDE\V3R6Mð\SYS;E:\CTTAS\IBMCLASS;%INCLUDE%
SET HELP=C:\CTTAS\HELP;%HELP%
SET BOOKSHELF=C:\CTTAS\HELP;%BOOKSHELF%
SET TMP=C:\CTTAS\TMP

Adding environment variables of your choice to this file is a way of specifying


variables that you always use without having to type them individually on the
OS/2 command line.
The variables in this file override environment variables in the CONFIG.SYS
file. You can append the original value of a variable using %variable%, as
shown in this PATH statement:
SET PATH=C:\CTTAS\BIN;%PATH%
Command line
When the SET command is used on the OS/2 command line, the values you
specify are in effect only for that OS/2 session. They override values previ-
ously specified in CONFIG.SYS or CTTASENV.CMD. You can append the
original value of a variable using %variable%.

Example of Setting Environment Variables


The following example could be used in the CTTASENV.CMD file or on the OS/2
command line. If the executable files that make up the compiler are in
C:\CTTAS\BIN, the following command adds this directory to the PATH variable:
SET PATH=C:\CTTAS\BIN;%PATH%

This command makes C:\CTTAS\BIN the first directory searched by the OS/2 oper-
ating system (after the current directory). To put the new directory at the end of the
search sequence, put %PATH% before the new directory name.

Chapter 5. Controlling Compiler Input 65


Controlling #include Search Paths

Source File Names in ICCAS


In addition to compiler options, you can also put file names into the ICCAS variable.
For example, if you specify SET ICCAS=test.cpp check.cpp, the command iccas
main.cpp causes test.cpp, check.cpp, and main.cpp to be compiled in that order.

This is the same as specifying iccas test.cpp check.cpp main.cpp on the OS/2
command line.

You can also name existing intermediate files (.qwo, created with the /Fw option) in
ICCAS. The compiler will process them according to the options specified on the
invocation command.

Controlling #include Search Paths


The #include preprocessor directive lets you retrieve source statements from sec-
ondary input files and incorporate them into your program.

You can nest #include directives in an included file. There is a limit of 128 levels
of nesting in the IBM VisualAge C++ for OS/400 compiler.

Compiler options and environment variables let you choose the disk directories
searched by the compiler when it looks for #include files.

This section describes how to specify #include file names and how to set up search
paths for these files.

#include Syntax
The following diagram shows the syntax of the #include directive:

55──#include──┬─<filename>─┬───────────────────────────────────5%
└─"filename"─┘

In the above figure, angle brackets indicate a system #include file, and quotation
marks indicate a user #include file.

#include File Name Syntax


You can specify any valid OS/2 file name in an #include directive. The file name
must be sufficiently qualified for the compiler to be able to locate the file.

If a path name is too long to fit on one line, you can place a continuation character,
or backslash (\), at the end of the unfinished line to indicate that the current line
continues onto the next line. The backslash can follow or precede a directory sepa-

66 IBM VisualAge C++ for OS/400 C++ User’s Guide


Controlling #include Search Paths

rator, or divide a name. For example, to include the following file as a user
#include file:
c:\cttas\include\mystuff\subdir1\subdir2\subdir3\myfile.h
you could insert one of the following #include directives in your program:
#include "c:\cttas\include\mystuff\subdir1\sub\
dir2\subdir3\myfile.h"
or
#include "c:\cttas\include\mystuff\subdir1\\
subdir2\subdir3\myfile.h"

Notes:
1. The continuation character must be the last non-white-space character on the line.
(White space includes any of the space, tab, new-line, or form-feed characters.)
The line cannot contain a comment.
2. The continuation character, although the same character as the directory sepa-
rator, does not take the place of a directory separator or imply a new directory.

Ways to Control the #include Search Paths


You can control the #include search paths in three ways:
Ÿ Use the /I, /Xc, and /Xi compiler options on the OS/2 command line when
invoking the compiler
Ÿ Use the /I, /Xc, and /Xi compiler options in the ICCAS environment variable
Ÿ Specify the search paths in the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 environ-
ment variables

See “#include File Search Options” on page 102 for more information on the
compiler options /I, /Xc, and /Xi.

#include Search Order


When the compiler encounters either a user or system #include file statement with a
fully-qualified file name, it looks only in the directory specified by that name.

When the compiler encounters a user #include file specification that is not fully
qualified, it searches for the file in the following places, in the order given:
1. The directory where the original top-level file was found.
2. Any directories specified using /I that have not been removed through the use of
/Xc. Directories specified in the ICCAS environment variable are searched
before those specified on the OS/2 command line.

Chapter 5. Controlling Compiler Input 67


Controlling #include Search Paths

3. Any directories specified using the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 envi-


ronment variables, provided that the /Xi option is not currently in effect.

When the compiler encounters a system #include file specification that is not fully
qualified, it searches for the file in the following places, in the order given:
1. Any directories specified using /I that have not been removed through the use of
/Xc. Directories specified in the ICCAS environment variable are searched
before those specified on the OS/2 command line.
2. Any directories specified using the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 envi-
ronment variables, provided that the /Xi option is not currently in effect.

Search Order for Externally Described Files


Header files created by the #pragma mapinc directive follow the same convention as
other user #include files. If header files are to be stored in a directory other than
the current directory, this directory must be on the search path for #include files as
described for user #include files.

By default, the compiler saves header files generated by the #pragma mapinc direc-
tive relative to the current directory, in the filename given on directive. When
searching for user include files, as described in “#include Search Order” on
page 67, the compiler does not search the current directory for the header file speci-
fied on the #include directive.

When the current directory is specified neither in any of the environment variables
nor on the command line, this behavior may cause compilation to fail. For example,
source file source.cpp, located in directory mydir1, specifies the following
directives:

#pragma mapinc("incfile", "MYLIB/MYFILE(\ALL)", )


other code
#include "incfile"

If you compile this file from directory mydir2 with the command:
iccas \mydir1\source.cpp

compilation will fail, because the header file incfile generated by the #pragma
mapinc directive is stored in the current directory mydir2, which is not searched for
user include files.

To avoid this situation, you may want to qualify the filename on the #include direc-
tive as shown below, to make sure the current directory will be searched:

68 IBM VisualAge C++ for OS/400 C++ User’s Guide


Controlling #include Search Paths

#pragma mapinc("incfile", "MYLIB/MYFILE(\ALL)", )

// other code

#include ".\incfile"

See the VisualAge C++ for OS/400 C++ Programming Guide, for detailed informa-
tion on externally described files.

Accumulation of Options
The #include search options are cumulative between the ICCAS and INCLUDE envi-
ronment variables and the OS/2 command line. For example, given the following
ICCAS and INCLUDE environment variables:

ICCAS=/I\payroll
INCLUDE_ASV3R6=c:\employee;\hourly
and the following OS/2 command line:
iccas /Xi+ /Ic:\purch test.cpp /Xi- /Xc
/Id:\prod f:\moe\min\jay.cpp

any system #include files referenced in the file test.cpp will be searched for first
in the directory \payroll and then in the directory c:\purch. Because the /Xi+
option was specified, none of the directories set in the INCLUDE_ASV3R6 environment
variable will be searched.

Using the same example, any user #include files referenced in test.cpp would be
searched for first in the current directory, then in the directory \payroll, and then in
c:\purch.

Any system #include files referenced in the file f:\moe\min\jay.c will be


searched for first in the d:\prod directory, then in the c:\employee directory, and
finally the \hourly directory. The directories specified in the INCLUDE_ASV3R6 vari-
able are searched because the /Xi- option overrides the /Xi+ option specified previ-
ously. The /Xc option removes the directories \payroll and c:\purch from the
current search path.

Any user #include files referenced in jay.c will be searched for in the following
directories, in the given order: f:\moe\min, d:\prod, c:\employee, and \hourly.

Chapter 5. Controlling Compiler Input 69


Setting the Source Code Language Level

Setting the Source Code Language Level


The compiler supports three language levels, ANSI, Extended, and Compatible, which
are described below.

To set a language level, do one of the following:


Ÿ Use one of the compiler options /Sa, /Se, or /Sc, either on the OS/2 command
line or in the ICCAS environment variable.
Ÿ Use a #pragma langlvl directive.

Note that a #pragma langlvl directive set in your source code overrides any
language-level compiler options specified on the OS/2 command line or in the ICCAS
environment variable.

When you set the language level, you also define the macro associated with that
level.

Choosing a Language Level


The choice of a language level depends on your application requirements:
Ÿ If you want your code to be portable across all ANSI-conforming systems, use
the ANSI language level.
Ÿ If you want to allow constructs compatible with older levels of the C++ language,
you should use the compatible language level.
Ÿ If you want to allow all VisualAge C++ for OS/400 language constructs, you
should use the extended language level.

Language Level Description


The following describes each language level and the corresponding compiler options:
1. ANSI. Allow only language constructs that conform to the proposed standards in
the ANSI committee's Draft - Proposed International Standard for Information
Systems - Programming Language C++ X3J16/92-00091. All non-ANSI con-
structs cause compiler error messages to be issued.
Use this language level to write code that is portable across ANSI-conforming
systems.
To set this language level, use either the /Sa option or #pragma langlvl(ansi),
which defines the macro __ANSI__.
Note: You may use the predefined macro __cplusplus to make source code
changes when you want to compile C code with the C++ compiler.

70 IBM VisualAge C++ for OS/400 C++ User’s Guide


Setting the Source Code Language Level

See the VisualAge C++ for OS/400 C++ Programming Guide for details on
using predefined macros.
2. Extended. Allow all IBM VisualAge C++ for OS/400 language constructs.
These include all constructs that fall under the ANSI Level and the IBM
VisualAge C++ for OS/400 extensions to this standard.
This is the default language level.
To explicitly state this default (for example, on the OS/2 command line to over-
ride a setting in the ICCAS environment variable), use the /Se option or #pragma
langlvl(extended), which defines the macro __EXTENDED__.
3. Compatible. Allow constructs and expressions that were allowed by earlier
levels of the C++ language.
When the language level is set to compatible:
Ÿ Classes declared or defined within classes or declared within argument lists
are given the scope of the closest non-class.
Ÿ typedefs and enumerated types declared within a class are given the scope
of the closest non-class.
Ÿ The overload keyword is recognized and ignored.
Ÿ An expression showing the dimension in a delete expression is parsed and
ignored. For example, in the expression delete [2ð] p;, 2ð is ignored.
Ÿ Conversions from const void\ and volatile void\ to void\ are allowed.
At other language levels, these conversions would require an explicit cast.
Ÿ Where a conversion to a reference type uses a compiler temporary type, the
reference need not be to a const type.
Ÿ You can bypass initializations as long as they are not constructor initializa-
tions.
Ÿ You can return a void expression from a function that returns void.
Ÿ operator++ and operator-- without the second zero argument are matched
with both prefix and postfix operators ++ and --.
Ÿ You can use the dollar ($) character in identifiers. Note that you can also
use $ in C++ files when the language level is set to extended.
Ÿ In a cast expression, the type to which you are casting can include a storage
class specifier, function-type specifier (inline or virtual), template
specifier, or typedef. At other language levels, the type must be a data
type, class, or enumerated type.
Ÿ You can have a trailing comma in a list of enumerators, for example enum E
{e , };

Chapter 5. Controlling Compiler Input 71


Compile-Time Limits

Ÿ Given the expression class A \a = new(x) A[1ðð];, the compiler looks


for a member operator new because the placement syntax (new(x)) is used.
The member operators are not typically used to allocate arrays.
Ÿ You can use the comma operator in a constant expression. This allows
comma expressions to be used in places like case labels and array bounds,
where they are normally prohibited.
Ÿ You can declare a member function using both the inline and static
keywords, for example,
inline static void payroll :: printCheque(void);
The static keyword is ignored.
Ÿ No error is generated if a function declared to return a non-void type does
not contain at least one return statement. Such a function can also contain
return statements with no value without generating an error.
Ÿ If two pointers to functions differ only in their linkage types, they are con-
sidered to be compatible types.
Use this language level to port older C or C++ code to the VisualAge C++ for
OS/400 product.
To select this language level use the /Sc option or #pragma langlvl(compat),
which defines the macro __COMPAT__.

Compile-Time Limits
The following limits apply when you compile C++ code with the cooperative
compiler:
Ÿ The maximum total size of variables in static storage is 16 773 104 bytes
Ÿ The maximum total size of variables in automatic storage for a single procedure
is 16 773 104 bytes
Ÿ The compiled object cannot contain more than 16 megabytes of encapsulated
code.
Ÿ The maximum number of arguments for ILE bound calls is 400
Ÿ The maximum number of arguments on a dynamic (OS-linkage) program call is
255
Ÿ The maximum length of identifiers is 4 kilobytes
Ÿ The maximum number of modules that can be specified for CRTPGM or
CRTSRVPGM is 300. To bind more than 300 modules, use bind directories
which allow you to specify all the modules you want to bind.

72 IBM VisualAge C++ for OS/400 C++ User’s Guide


Output File Types

6 Controlling Compiler Output

The compiler can produce several types of output. This chapter describes the various
output files and the level of information that can be generated. Topics include:
Ÿ Working with different compiler output file types
Ÿ Using precompiled header files
Ÿ Inlining user code
Ÿ Compiling applications for a V3R1 IMPI run-time environment

Output File Types


Depending on the compiler options you choose, the compiler produces a variety of
output files:
*MODULE
A module object \MODULE is created for each C++ source file. This
object is located on the AS/400. It can be created only if you compile in
connected mode.
*PGM or *SRVPGM
A program object \PGM, or a service program object \SRVPGM is created if
you also invoke the binder. These objects are located on the AS/400.
They can be created only if you compile in connected mode.
Intermediate Code File .qwo
An intermediate code file .qwo is created for each source file. This file
is located on the OS/2 workstation
Listing File .lst
A listing file .lst can be created for each C++ source file, containing
information about the compilation. This file is located on the OS/2 work-
station.
Precompiled Header File
Precompiled header files are located on the OS/2 workstation in file
csetcpp.pch, in a subdirectory relative to the directory in which the ori-
ginal header file is located.
Template-Include File .h
Template-include files are located on the OS/2 workstation.
See the VisualAge C++ for OS/400 C++ Programming Guide for more
information about these files.

 Copyright IBM Corp. 1995 73


Output File Types

Preprocessor-Output File .h
A preprocessor output file .i can be generated for each C++ source file.
This file is located on the OS/2 workstation. You can use it to find pos-
sible programming errors.
Note: This information is not intended to be used as a programming
interface.
Browser-Listing File .pdb
A browser listing file .pdb can be created for use by the IBM VisualAge
C++ for OS/400 browser.
Diagnostic information
Diagnostic information helps find possible programming errors.
Note: This information is not intended to be used as a programming
interface.
Messages
Messages include the compiler logo, help messages, and return codes (for
example, 0 for a compile without errors).

Intermediate Code Files and Module Objects


On the OS/2 workstation, the compiler creates an intermediate code file with the
extension .qwo for each source code file. In connected mode, this intermediate code
file is transferred to the AS/400, where it is processed into a module object
(\MODULE). One or more module objects can be bound to create either program
(\PGM) or service program (\SRVPGM) objects. See “Code Generation Options” on
page 117 for more information on using compiler options to specify the type of
object to be created.

Intermediate code files (.qwo) generated by the compiler are deleted when the corre-
sponding module objects have been created on the AS/400.

In the following cases intermediate code files remain on the OS/2 workstation to be
used to create module objects at a later time:
Ÿ Module creation is not successful
Ÿ Module creation is not attempted because of your choice of compiler options
Ÿ You compile in disconnected mode

Optimizing Object Code


The compiler can perform many optimizations on object code, such as local optimiza-
tions, common subexpression elimination, and loop optimizations.

Generally, the higher the optimization request, the longer it takes to create the object.
At run time, highly optimized programs should run faster than corresponding pro-

74 IBM VisualAge C++ for OS/400 C++ User’s Guide


Output File Types

grams created with a lower optimization level. However, I/O intensive programs will
show little or no difference.

Optimization techniques apply to individual modules. The AS/400 levels are no opti-
mization (*NONE), some optimization (*BASIC), maximum optimization (*FULL), and
level 40 optimization.

These levels have the following meaning:


*NONE Generated code is not optimized. This level has the shortest compile
time. It allows variables to be displayed and modified while debugging.
*BASIC Some optimization is performed on the code. This level allows user vari-
ables to be displayed but not modified while debugging.
FULL Full optimization is performed on the generated code. During a debug
session, user variables may not be modified but may be displayed. The
presented values may not be the current value of the variable.
Level 40 All optimizations done at level 30 (*FULL) are performed on the gener-
ated code. In addition, code is eliminated from procedure prologue and
epilogue routines that enable instruction trace and call trace system func-
tions.

You determine the level of optimization for a module through the /O compiler option.
By default, optimization is turned off (/O-).

The following list shows the relationship between AS/400 optimization levels and
iccas compiler options:
*NONE or 10
/O- or /O1ð
*BASIC or 20
/O2ð
*FULL or 30
/O3ð or O+
level 40 /O4ð

Because optimization at level *FULL, or higher, can significantly affect the order of
your program instructions, you may need to be aware of certain debugging limita-
tions. See Part 4, “Debugging Your Program” on page 199 for debug consider-
ations.

Chapter 6. Controlling Compiler Output 75


Output File Types

See “Code Generation Options” on page 117 for more information on using com-
piler options to control optimization. For more information on how you can optimize
your code, see the chapter on optimizing code in the Programming Guide.

Generating Debugger Information


You can specify the debug compiler option /Ti to instruct the compiler to include the
information necessary for debugging a program in the module object.

When you specify the /Ti option, do not turn on optimization (/O+, /Oi+), because
accurate symbol and type information may not be available, due to the optimization
process. Debugging information generated with optimization is limited to setting
breakpoints at function entry and function exit.

See “Debugging and Diagnostic Information Options” on page 108 for more
information on using compiler options to control the generation of debugging infor-
mation.

See Part 4, “Debugging Your Program” on page 199 for information on debug-
ging AS/400 applications with the VisualAge C++ for OS/400 Cooperative Debugger,
or with the ILE source-level debugger.

Generating Browser Information.


To create browser information, use the /Fb option to produce .pdb files that the
browser can use to display information about your program.

See “Output File Management Options” on page 97 for more information on gen-
erating browser files.

Program and Service Program Objects


By default, in connected mode, the compiler creates one program object (\PGM) for
each compiler invocation. If you specify the /C option, the compiler only generates
module objects (\MODULE), which you can then bind separately to create a program or
a service program.

Use the compiler default settings to create a program object from your source files, or
use the /B"crtsrvpgm srvpgm(xxx/yyy)" option to create a service program.
See Chapter 8, “Creating an OS/400 Program” on page 127 and Chapter 9, “Cre-
ating a Service Program” on page 141 for more information on the use of programs
and service programs.

See “Other Options” on page 119 for more information on the compiler options
you can use to create program and service program objects.

76 IBM VisualAge C++ for OS/400 C++ User’s Guide


Output File Types

Compiler Listings
When you compile a program, you can produce a listing file that contains information
about the source program and the compilation. You can use this listing to help you
debug your programs.
Note: The compiler listing file is not intended to be used as a programming inter-
face.

The listing will show the options used by the compiler, any error messages, and a
standard header that shows:
Ÿ The product number
Ÿ The compiler version and release number
Ÿ The date and time compilation commenced
Ÿ A list of the compiler options in effect

Depending on the listing options you specify, further information may be included in
the listing. See “Listing File Options” on page 103 for information on how to
use compiler options to specify the information and format of this file.

Temporary Files
The compiler creates and uses temporary files during compilation. These files are
usually erased at the end of a successful compilation; however, if the compilation is
interrupted, they may be left on the disk. They are located in the path specified by
the TMP environment variable. If this variable is undefined, the compiler uses the
current directory.

For more information on the TMP variable, see “OS/2 Environment Variables for
Compiling” on page 62.

Messages and Return Codes


Messages and return codes provide information about the compilation of your files
and help you analyze the potential cause for compilation errors.

Error Messages
You can use compiler options to control:
1. The level of error message that the compiler outputs and that increments the error
count maintained by the compiler (with the /Wn option).
2. How many errors are allowed before the compiler stops compiling (with the /Nn
option).
3. The diagnostics run against the code (with the /Wgrp option).

Chapter 6. Controlling Compiler Output 77


Output File Types

See “Debugging and Diagnostic Information Options” on page 108 for more
information on using the compiler options to control messages.

Redirecting Messages to a File


Messages, warnings, and errors, are written to stdout. You may sometimes want to
redirect them to a file instead. Use the redirection symbol (>), and a file name; for
example:
iccas myfile.cpp > myfile.err

Return Codes
The compiler indicates the highest return code it receives while performing the
various phases of compilation. These codes are:
Code Meaning
0 The compilation was completed, and no errors were detected. Any
warnings have been written to stdout.
12 Error detected; compilation may have been completed, but no module object
was created on AS/400.
16 Severe error detected; compilation terminated abnormally; no module object
was created on AS/400.
Note: Problems with the transfer of intermediate code files to AS/400 or
with the connection itself may result in either return code 12, or 16.
20 Unrecoverable error detected; compilation terminated abnormally and
abruptly; no module object was created on AS/400.
If the error code is greater than 20, contact your IBM service representative.

For every compilation, the compiler generates a return code that indicates to the oper-
ating system the degree of success or failure it achieved.
Note: If you compile multiple files with one invocation, for example:
iccas p1.cpp p2.cpp p3.cpp
you get the last return code before the command ended. This means:
Ÿ If all files compile successfully, the return code indicates the successful com-
pletion.
Ÿ If not all files compile successfully, the return code indicates the degree of the
first failure that occurred and compilation terminates. For example, if compila-
tion of p2.cpp returns a code other than 0, the compiler does not attempt to
compile p3.cpp and returns the code for p2.cpp.

78 IBM VisualAge C++ for OS/400 C++ User’s Guide


Precompiled Header Files

AS/400 Job Logs


Enter the Work Configuration Status (WRKCFGSTS) command on an AS/400
command line to display AS/400 job logs. The syntax of the WRKCFGSTS
command is:

55──WRKCFGSTS──\CTL──RMTLOCNAME────────────────────────────────5%

The parameter *CTL specifies that the status for controllers is to be displayed.

The parameter RMTLOCNAME specifies the remote-location name of the OS/2 work-
station for which you want the status displayed.

For example, after issuing a compiler command from your OS/2 workstation with the
remote-location name OMNXID, switch to an AS/400 session, and enter the following
command on the AS/400 command line:
WRKCFGSTS \CTL OSNXID

The Work with Configuration Status (WRKCFGSTS) command is used to display and
to work with configuration status functions. When you run this command, the Work
with Configuration Status display is shown.

Type option 5 (Work with job) next to the entry that shows the job name QZRCSRVR.
Then select:
1ð. Display job log, if active or on job queue
to access the Display Job Log display, where you find information about the com-
mands processed by the job and the messages returned from running those commands.

If you are displaying a batch job, you can see commands that are still to be processed
(identified by ".."). For specific information about messages, put the cursor on the
message you want information about and press the Help key. An additional message
information display will then be shown.

Precompiled Header Files


To create a precompiled header file specify the /Fi compiler option. This option lets
you create or recreate precompiled versions of every source header file used during
that compilation.

To use precompiled header files, specify the /Si option.

Chapter 6. Controlling Compiler Output 79


Precompiled Header Files

Location and Time Stamp


The precompiled version of each header file is created in a subdirectory called
CSETASP under the directory containing the original header file. For example, the
precompiled version of d:\employee\wages.h is placed in the directory
d:\employee\CSETASP. If the subdirectory does not exist, the compiler creates it for
you.

The file name given to the precompiled header file is the same as the original name.
The timestamp is also the same as that of the original file so the compiler can ensure
that the precompiled file is current. Current means that the original header file has
not been updated since the creation of the precompiled header file.

Search Path
For each #include statement, the compiler determines which header file is required
using the usual #include search path ( see “#include Search Order” on page 67).
It then looks for the precompiled version in the CSETASP subdirectory under the direc-
tory containing the original header file. It uses the precompiled version if it exists
and is current. For example, given:
Ÿ d:\employee\local contains wages.h and salary.h
Ÿ d:\employee\temp contains salary.h
Ÿ The search path is d:\employee\temp;d:\employee\lo cal
Ÿ The source file contains the statements:
#include "wages.h"
#include "salary.h"

the compiler looks for the precompiled header files as follows:


Ÿ wages.h in the directory d:\employee\local\CSETASP
Ÿ salary.h in the directory d:\employee\temp\CSETASP

When a Precompiled Header File is Not Used


A precompiled header file is only used if the original header file exists. If the ori-
ginal file has been deleted, renamed, or moved to another directory, the precompiled
version is not used. For example, if you erase d:\employee\temp\salary.h, the
compiler does not use the precompiled header file in d:\employee\temp\CSETASP.
Instead it continues along the search path, finds d:\employee\local\salary.h, and
uses the precompiled header file for this file if it exists and is current.

Creating and Maintaining Precompiled Header Files Automatically


You can use /Fi and /Si together to automatically create and maintain precompiled
header files for your application. If you use the options consistently, precompiled
header files are created if they do not exist, and used if they do. When a source file
is changed, the precompiled version is automatically regenerated.

80 IBM VisualAge C++ for OS/400 C++ User’s Guide


Inlining User Code

Restrictions When Using Precompiled Header Files


When you use precompiled header files, keep the following restrictions in mind:
Ÿ Precompiled header files do not appear in any listing files.
Ÿ If you specify /P to run the preprocessor only, the /Fi and /Si options are
ignored.

Inlining User Code


By default, the compiler inlines intrinsic and built-in functions. Inlining means that
the compiler replaces the function call with the actual code for the function at the
point where the call was made.

You can also request that the compiler inline the code for your own, user-defined,
functions. There are three ways to inline user code:
1. Use the function specifier inline for functions you want the compiler to inline.
2. Use the /Oi option with a value parameter to inline functions smaller than the
value specified.
3. Define C++ member functions in a class declaration.
Note: Even when you use these methods, you do not have absolute control over
whether functions are inlined or not. This decision is up to the compiler. Requesting
that a function be inlined makes it a candidate for inlining. This does not necessarily
mean that the function will in fact be inlined.

Using the
inline Keyword

Use the inline function specifier to qualify either the prototype or definition of the
functions you want to have inlined. For example, inline int silly(char c);
declares that silly is to be inlined.

The inline keyword has the same meaning and syntax as the storage class static.
When you turn inlining on, the keyword also causes the function it qualifies to be
inlined. In addition, C++ member functions that are defined in a class declaration are
considered candidates for inlining by the compiler.

Using the /Oi Option


The /Oi option controls whether user functions are inlined or invoked through a func-
tion call:
/Oi- No user code is inlined. This is the default.
/Oi+ Functions qualified with the inline keyword are inlined.

Chapter 6. Controlling Compiler Output 81


Inlining User Code

/Oivalue Functions qualified with the inline keyword are inlined, as are all other
functions that are less than or equal to value in abstract code units
(ACUs) as measured by the compiler. This option is called auto-inlining.
In general, choosing the functions you want inlined yields better results
than auto-inlining.

The /Oi option does not affect the inlining of intrinsic VisualAge C++ for OS/400
library functions. Instead, you must parenthesize the function call to disable the
inlining of intrinsic library functions, for example:
(strcpy)(str1, str2);

While parenthesizing works with intrinsic functions, there is no way to disable


inlining for your user-defined functions, meaning you cannot request that specific
functions not be inlined.

Parenthesizing does also not work with some library functions that are are imple-
mented as built-in functions. In their case, there is no backing code in the library.
Therefore, the compiler must inline them in every case.

See the VisualAge C++ for OS/400 IBM Open Class Library and IBM Access
Class Library for OS/400 Reference for a list of all the intrinsic and built-in library
functions.

If you use auto-inlining, the parameter value on the /Oi command has a range
between 0 and 65535 abstract code units (ACUs). The number of ACUs that com-
prise a function is proportional to the size and complexity of the function. Because
the compiler calculates ACUs based on internal algorithms, you can only estimate the
number of ACUs for a given function. The following code samples provide some
examples on which you can base your estimates.

The following function is 33 ACUs:

int florence(char a, int b)


{
if(a != 1ð)
b++;
else
b += 1ð;
return(a);
}

The next function is 51 ACUs:

82 IBM VisualAge C++ for OS/400 C++ User’s Guide


Inlining User Code

int sanjay(long par1, long par2)


{
while(par1)
{
if(par2)
test3();
par1--;
}

if(par1)
testing();
par1 += par2;
}

Messages are generated to tell you which functions are inlined based on the value
you specified. No messages are generated for functions qualified with the inline
keyword, or for C++ functions defined in a class declaration. For most applications,
the most effective value for auto-inlining is between 5 and 20.
Note: The value required to inline a specific function may be slightly larger when
/O+ is specified than when /O- is specified.

Benefits of Inlining
Inlining user code eliminates the overhead of the function call and linkage, and also
exposes the function's code to the optimizer, resulting in faster code performance.
Inlining produces the best results when:
Ÿ The overhead for the function is nontrivial, for example, when functions are
called within nested loops.
Ÿ The inlined function provides additional opportunities for optimization, such as
when constant arguments are used.
For example, given the following function:

Chapter 6. Controlling Compiler Output 83


Inlining User Code

void glen(int a, int b)


{
if (a == 1ð)
{
switch(b)
{
case 1: .
:
case 2ð: puts("b is 2ð");
break;
case 3ð: .
:
default: .
:
}
}
}
and assuming your program calls glen several times with constant arguments, for
example, glen(1ð, 2ð);, each call to glen causes the if and switch
expressions to be evaluated. If glen is inlined, the compiler can then optimize
the function. The evaluation of the if and switch statements can be done at
compile time and the function code can then be reduced to only the puts state-
ment from case 2ð.

The best candidates for inlining are small functions that are called often.

To improve performance further:


Ÿ Use constant arguments in inlined functions whenever possible. Functions with
constant arguments provide more opportunities for optimization.
Ÿ If you have a function that is called many times from a few functions, but infre-
quently from others, create a copy of the function with a different name and
inline it only in the functions that call it often.
Ÿ Turn optimization on.

Drawbacks of Inlining
Inlining user code usually results in a larger executable module because the code for
the function is included at each call site. Because of the extra optimizations that can
be performed, the difference in size may be less than the size of the function multi-
plied by the number of calls.

Inlining can also result in slower program performance, especially if you use auto-
inlining. Because auto-inlining looks only at the number of ACUs for a function, the

84 IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiling for V3R1 Runtime Environment

functions that are inlined are not always the best candidates for inlining. As much as
possible, use the _Inline or inline keyword to choose the functions to be inlined.

When you use inlining, you need more stack space. When a function is called, its
local storage is allocated at the time of the call and freed when it returns to the
calling function. If that same function is inlined, its storage is allocated when the
function that calls it is entered, and is not freed until that calling function ends.
Ensure that you have enough stack space for the local storage of the inlined functions.

Restrictions on Inlining
The following restrictions apply to inlining:
Ÿ You cannot inline functions that use a variable number of arguments.
Ÿ You cannot declare a function as inline after it has been called.
Ÿ To use inline, the code for the function to be inlined must be in the same
source file as the call to the function. To inline across source files you must
place the function definition (qualified with inline) in a header file that is
included by all source files where the function is to be inlined.
Ÿ Turn off inlining (/Oi-) if you plan to debug your executable module. Inlining
can make debugging difficult; for example, if you set an entry breakpoint for a
function call but the function is inlined, the breakpoint does not work.
Ÿ A function is not inlined during an inline expansion of itself. For a function that
is directly recursive, the call to the function from within itself is not inlined. For
example, given three functions to be inlined, A, B, and C, where:
– A calls B
– B calls C
– C calls back to B
the following inlining takes place:
– The call to B from A is inlined.
– The call to C from B is inlined.
– The call to B from C is not inlined because it is made from within an inline
expansion of B itself.

Compiling Applications to Run in an AS/400 V3R1 IMPI Environment


VisualAge C++ for OS/400 has been developed primarily to provide the capability of
building C++ applications for the new AS/400 Reduced Instruction Set Computer
(RISC), beginning with Version 3, Release 0 of the Operating System/400.

Under certain circumstances you may want to compile your applications instead to
target Version 3, Release 1 of the Operating System/400 that is available on Internal

Chapter 6. Controlling Compiler Output 85


Compiling for V3R1 Runtime Environment

Microprogram Instruction (IMPI) computers. VisualAge C++ for OS/400 supports


both run-time environments, but you should be aware of certain limitations discussed
below.

Development Environment
The development environment for VisualAge C++ for OS/400 is always an OS/2
workstation connected to an AS/400 RISC machine running OS/400, Version 3,
Release 6. It is not possible to connect your OS/2 workstation to an AS/400 V3R1
IMPI system and successfully compile C++ source code with VisualAge C++ for
OS/400

Instead, you must create program (\PGM) and service program (\SRVPGM) objects on
the V3R6 RISC system, and then save/restore these objects on a V3R1 IMPI system.

Run-Time Environment
On the iccas compiler invocation command you specify the environment in which you
plan to later run your C++ application through the /ASv3r1 compiler option.

/ASv3r1- is the default for the iccas command and results in the creation of
program and service program objects that run on an AS/400 V3R6 RISC machine. If
you specify /ASv3r1+ instead, the resulting program or service program objects can
be run on an AS/400 V3R1 IMPI machine only.
Note: Applications specifically compiled to run on AS/400 V3R1 IMPI machines
are not upward compatible with V3R6 RISC machines. If you are planning to
develop applications for V3R1 that you may later want to run on a V3R6 RISC
machine, you must compile such applications twice, using once the /ASv3r1 option,
and once the /ASv3r1- option. This results in the creation of two separate applica-
tions, each targeting a different run-time environment.

Characteristics of the V3R1 Run-Time Environment


The V3R1 run-time environment has the following characteristics:
Ÿ The C++ run-time environment provides support for standard, collection, applica-
tion support and binary coded decimal classes
Ÿ The default target file system is the Integrated File System (IFS)
Ÿ Applications can be debugged with the ILE source-level debugger
Ÿ The language environment supports static initialization.

Limitations of the V3R1 Run-Time Environment


The V3R1 run-time environment has the following limitations:
Ÿ The C++ run-time environment does not provide support for System Object
Model (SOM) classes

86 IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiling for V3R1 Runtime Environment

Ÿ There is no support for multiple entry points


Ÿ There is no system support for long procedure names
Ÿ Optimization level 40 is not available; you cannot use compiler option /O4ð
Ÿ Performance explorer tools are not available; you cannot use compiler option
/ASp

Limitations when Debugging Applications Targeting V3R1


When debugging applications that have been compiled to run in a V3R1 IMPI envi-
ronment you encounter the following limitations:
Ÿ You cannot use the Cooperative Debugger to debug your application
Ÿ You cannot display reference variables
Ÿ You must use hashed names; a listing for mangled names and their corresponding
hashed names is provided
Ÿ You cannot look at bit fields in anonymous unions
Ÿ You cannot debug within class scope
Ÿ You may encounter problems with casting

Copying V3R1 System Header Files to Your OS/2 Workstation


There are some differences in system specific functions and structures between
system header files for V3R6 and V3R1.

During the installation of VisualAge C++ for OS/400 on your OS/2 workstation, the
install program automatically installs the V3R1 system header files in addition to the
V3R6 header files.
Note: Standard header files can be used on both V3R6 and V3R1 systems.

Chapter 6. Controlling Compiler Output 87


Compiling for V3R1 Runtime Environment

88 IBM VisualAge C++ for OS/400 C++ User’s Guide


7 Setting Compiler Options

You use compiler options to specify different aspects of the compilation and binding
of your program. This chapter describes the options and how to use them. The
topics include:
Ÿ Specifying compiler options
Ÿ Scope of compiler options
Ÿ Compiler option classification
Ÿ Options summary
Ÿ Output file management options
Ÿ #include file search options
Ÿ Listing file options
Ÿ Debugging and diagnostic information options
Ÿ Source code options
Ÿ Preprocessor options
Ÿ Code generation options
Ÿ Other options

Specifying Compiler Options


Compiler options are not case sensitive, so you can specify them in lower-, upper-, or
mixed case. You can also substitute a hyphen (-) for the slash (/) preceding the
option. For example, -Rn is equivalent to /Rn. Lower-and uppercase, hyphens, and
slashes can all be used on one command line, as in:
iccas /ls -SI -oI /Fl prog.cpp

You do not need the plus symbol (+) when specifying an option: the forms /Fb+ and
/Fb are equivalent.

Many options have parameters. See “Using Parameters with Compiler Options”
on page 91 for more information on these parameters.

You can specify compiler options in several ways:


Ÿ On the OS/2 command line
Compiler options specified on the OS/2 command line override any options pre-
viously specified in the ICCAS environment variable (as described below and in
“OS/2 Environment Variables for Compiling” on page 62 ). To compile a
source file from an OS/2 command line, enter the following command at the
OS/2 prompt:

 Copyright IBM Corp. 1995 89


iccas /option(s) filename
For example, to compile the source file myprog.cpp with the browser option /Fb
enter:
iccas /Fb myprog.cpp
Ÿ In the ICCAS environment variable
Frequently used OS/2 command-line options can be stored in the ICCAS environ-
ment variable. This method is useful if you find yourself repeating OS/2
command line options every time you compile. You can also specify source file
names in ICCAS.
The ICCAS environment variable can be set either from the OS/2 command line,
in a command (.CMD) file, or in the CONFIG.SYS file. If it is set on the OS/2
command line or by running an OS/2 command file, the options will only be in
effect for the current session. If it is set in the CONFIG.SYS file, the options
will be in effect every time you use iccas unless you override them using a
.CMD file or by specifying options on the OS/2 command line.
For example, to specify that a source listing be generated for all compilations and
that the macro DEBUG be defined as 1, use the following command at the OS/2
prompt (or in your CONFIG.SYS file if you want these options every time you
use the compiler):
SET ICCAS=/Ls+ /DDEBUG::1
(The double colon must be used because the "=" sign is not allowed in OS/2
environment variables.)
Now, when you type iccas prog1.cpp to compile prog1.cpp, the macro DEBUG
will be defined as 1, and a source listing will be produced.
Options specified on the OS/2 command line override the options in the ICCAS
environment variable. For example, the following compiler invocation takes pre-
cedence over the ICCAS setting in the last example:
iccas /Ls- /UDEBUG myprog.cpp
See “OS/2 Environment Variables for Compiling” on page 62 for more infor-
mation about using ICCAS and other environment variables.
Ÿ Combining ICCAS and OS/2 Command Line Options
When you specify compiler options both in the ICCAS environment variable and
on the OS/2 command line, the compiler evaluates both sets of options. When
the compiler is invoked:
1. The string associated with ICCAS is retrieved
2. The OS/2 command line is retrieved

90 IBM VisualAge C++ for OS/400 C++ User’s Guide


3. The OS/2 command line is appended to the ICCAS string, combining the
two into a single OS/2 command line
4. This combined OS/2 command line is read from left to right, and the
compiler-option-precedence rules are applied
5. The files are compiled using the options as interpreted in the previous step
Ÿ In the WorkFrame environment
If you have installed WorkFrame, you can set compiler options through options
dialogs. You can use these dialogs when you create or modify a project.
Options you select while creating or changing a project are saved with that
project.
See Part 1, “Developing OS/400 Applications with WorkFrame” on page 1
for more information on using WorkFrame.

Using Parameters with Compiler Options


All compiler options that take parameters obey to the following rules:
Ÿ If a parameter is required, zero or more spaces may appear between the option
and the parameter. For example, both /DDEBUG and /D DEBUG are valid.
Ÿ If a parameter is optional, no space is allowed between the option and parameter.
For example, /FlMylist.lst is valid, but /Fl Mylist.lst is not.

The syntax of the compiler options varies according to the type of parameter that is
used with the option. There are five types of parameters:
Ÿ Strings
Ÿ Switches
Ÿ Numbers
Ÿ File names
Ÿ File extensions

Strings
If the option has a string parameter, the string must be enclosed by a pair of quota-
tion marks if there are spaces in the string. For example:
/V"Version 1.ð"
is correct. If there are no spaces in the string, the quotation marks are not necessary.
For example, both /VNew and /V"New" are valid.

If the string contains double quotation marks, precede them with the backslash (\)
character. For example, if the string is abc"def, specify it on the OS/2 command
line as "abc\"def". This combination is the only valid escape sequence within string
options. Do not end a string with a backslash, as in "abc\".

Chapter 7. Setting Compiler Options 91


Do not put a space between the option and the string.

Switches
Some options are used with plus (+) or minus (-) signs. If you do not use either
sign, the compiler processes the option as if you had used the + sign. When you use
an option that uses switches, you can combine them. For example, the following
compiler invocations have the same result:
iccas /Fb+ /Fi+ /Fl+ /Fo- file.cpp
iccas /Fbilo- file.cpp

Note that the (-) sign applies only to the switch immediately preceding it.

Numbers
When an option uses a number as a parameter, do not put a space between the option
and the number. For example:
/AScp37

File Names, Extensions, and Paths


When compiler options take file names as parameters, the following rules apply:
Ÿ If a file name contains spaces (as permitted by the High Performance File System
(HPFS)) or any elements of the HPFS extended character set, the file name must
be enclosed in quotation marks. In such a case, do not put a space between the
option and a file name or directory.
Ÿ The compiler uses defaults unless you specify output-file extensions. For
example, if you specify /Flcome, the listing file will be called come.lst.
Note: If you really want to call the listing file come, specify /Flcome.. The
period at the end of the filename specifies a null extension.
Ÿ If you use an option without using an optional name parameter, the name of the
following source file and the default extension are used.
Ÿ If you want to use a file that is in the current directory, specify only the file
name. For example, if the current directory is E:\, and the source file is
E:\myprog.cpp, you invoke the compiler with iccas myprog.cpp, using default
values.
Ÿ If the file is not in the current directory, specify the path and file name; for
example:
iccas /Fb F:\mydir\myprog.cpp

92 IBM VisualAge C++ for OS/400 C++ User’s Guide


Scope of Compiler Options
Options apply only to the source files that follow the option. The last, or rightmost,
occurrence of these options is the one that is in effect for the source file or files that
follow it.

In the following example, the file module1.c is compiled with the option /Fb-
because this option follows /Fb+:
iccas /Fb+ /Fb- module1.cpp

In the following invocation, the file module1.cpp is compiled with the /Fb+ option,
while module2.cpp is compiled with /Fb-:
iccas /Fb+ module1.cpp /Fb- module2.cpp

When you are compiling programs with multiple source files, an option is in effect
for all the source files that follow it. For example, if you enter the following OS/2
command:
iccas /Oi+ prog1.cpp /Fb sub1.cpp /Xc /Oi- sub2.cpp
Ÿ The file prog1.cpp is compiled with the option /Oi+.
Ÿ The file sub1.cpp is compiled with the options /Oi+ and /Fb+.
Ÿ The file sub2.cpp is compiled with the options /Oi-, /Fb+ and /Xc.

The name of the program object is the same as the name of the first source file
without its extension .cpp. In this example the program object will be called PROG1.

Options Having a Special Scope


The following options do not behave as described above:
/D Defines a preprocessor macro. /D is different from other options in that
the first definition of a macro is used. If a preprocessor macro is defined
more than once, a warning appears.
/I Sets search paths for #include files. This option is cumulative. If you
specify the option more than once, the parameters you specify are
appended to the parameters previously stated. For example, the OS/2
command
iccas /Ia: /Ib:\cde /Ic:\fgh prog.cpp
causes the following search path to be built:
a:;b:\cde;c:\fgh
/B Passes options to the binder. Like /I, this option is cumulative. If you
specify the option more than once, the parameters you specify are
appended to the parameters previously stated. All options on the OS/2

Chapter 7. Setting Compiler Options 93


command line, and in environment variables, are accumulated before the
modules are bound. The options affect all modules to be bound.
For example, the OS/2 command:
iccas /B"crtpgm pgm(mylib/cost)" /Ti+ /B"bndsrvpgm(mylib/serv1)" cost.cpp
is equivalent to specifying:
iccas /B"crtpgm pgm(mylib/cost) bndsrvpgm(mylib/serv1)" /Ti+ cost.cpp
/Q Controls the display of the compiler logo. This option is global and
applies to all source files on the OS/2 command line. It can follow the
last file on the OS/2 command line. If it is specified more than once, the
last occurrence of the option is the one in effect.

Related Options
Some options are required with other options:
Ÿ If you specify the listing file option /Le (expand macros), or one of /Li or /Lj
(expand #include files), you must also specify the /Ls option to include the
source code.

Conflicting Options
Some options are incompatible with other options. If options specified on the OS/2
command line are in conflict, the following rules apply:
Ÿ The option ( /Fb) to produce a browser file takes precedence over the precom-
piled header file option (/Si).
Ÿ The syntax check option ( /Fc) takes precedence over the output file generation
(/Fb, /Fo, and /Ft), intermediate code generation ( /Fw), and preprocessor (
/P, /Pc, /Pd, and /Pe) options.
Ÿ The option (/Fo-) to not create a module object (\MODULE) takes precedence over
the option ( /Ti) to include debug information in the object.
Ÿ The options (/Li and /Lj) to expand #include files in the listing take preced-
ence over the precompiled header file options ( /Fi and /Si).
Ÿ The option (/Lj+) to expand user and system #include files takes precedence
over the option (/Li) to expand user #include files only.
Ÿ The preprocessor options (/P, /Pc, /Pd, and /Pe) take precedence over the
output file generation (/Fb, /Fl, /Fo, and /Ft), intermediate code generation
(/Fw), precompiled header file (/Fi and /Si), and all listing file ( /L) options.

94 IBM VisualAge C++ for OS/400 C++ User’s Guide


Compiler Option Classification
The compiler options are divided into groups by function:
Ÿ “Output File Management Options” on page 97
/ASd /ASl /ASr /F
Ÿ “#include File Search Options” on page 102
/I /X
Ÿ “Listing File Options” on page 103
/L
Ÿ “Debugging and Diagnostic Information Options” on page 108
/N /Ti /W
Ÿ “Source Code Options” on page 112
/S /Sn
Ÿ “Preprocessor Options” on page 114
/D /P /U
Ÿ “Code Generation Options” on page 117
/ASi /ASp /O
Ÿ “Other Options” on page 119
/ASa /AScp /ASn /ASt /ASv3r1 /B /C /J /Q /Tl /V

The table that follows gives all options, in all groups, in alphabetical order. The
options are described in more detail in the sections following the table.

Options Summary

Figure 9 (Page 1 of 3). Compiler Options Summary


Option Description Default Page
/? Display list of compiler options with descriptions None 120
/ASa[l|c|u|a|e|] Specify module authority granted to users who do not have spe- /ASal 120
"list-name" cific authority
/AScp[n] . Specify the code page number for the target AS/400 system value specified in 121
ICCASCP
/ASd[+|-] Save header files generated from the #pragma mapinc directive /ASd+ 98
/ASddir
/ASi[+|-] Use integrated file system APIs instead of standard, non- /ASi+ 117
integrated-file system function

Chapter 7. Setting Compiler Options 95


Figure 9 (Page 2 of 3). Compiler Options Summary
Option Description Default Page
/ASlname Specify destination library name none 98
/ASnname Specify the name of the AS/400 system connection to use None 121
/ASp[-|1|2a|2n|3a|3n] Generate performance-data-collection code /ASp1 118
/ASr[+|-] Replace a module object. /ASr+ 99
/ASt"text" Specify text description for module /Blanks 122
/ASv3r1[+|-] Compile source files to create program or service program /ASv3r1- 122
objects that run in a V3R1 IMPI environment
/B"options" Pass options to the binder, in addition to default options /B"" 122
/C[+|-] Perform compile without binding, instead of compiling and /C- 123
binding
/Dname[=n] Define preprocessor macros None 115
/Dnname[::n]
/Fb[+|-] Produce a browser file /Fb- 99
/Fc[+|-] Perform syntax check only, instead of a full compile /Fc- 99
/Fi[+|-] Create precompiled header file /Fi- 100
/Fl[+|-][dir][name] Produce listing file /Fl- 100
/Fo[+|-][name] Control and name module object. /Fo+ 100
/Ft[+|-] Control and direct files for template resolution /Ft+ 101
/Ftdir
/Fw[+|-][dir][name] Create intermediate code files only, instead of a full compilation /Fw- 101
/Ipath[;path] Specify #include search paths, in addition to directory of source No additional 103
file and paths in the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 paths
environment variables
/J[+|-] Set unspecified char variables to unsigned char /J+ 123
/L[+|-] Produce a minimal listing file /L- 104
/La[+|-] Include a minimal layout in the listing file /La- 105
/Lb[+|-] Include a layout in the listing file /Lb- 105
/Le[+|-] Expand macros in the listing file /Le- 105
/Lf[+|-] Set all listing options on /Lf- 106
/Li[+|-] Expand user #include files in the listing file /Li- 106
/Lj[+|-] Expand user and system #include files in the listing file /Lj- 106
/Lpnum Set page length of the listing file /Lp66 106
/Ls[+|-] Include the source code in the listing file /Ls- 107
/Lt"string." Set title string for the listing file Name of first 107
source file
/Lu"string" Set subtitle string in the listing file /Lu"" 107

96 IBM VisualAge C++ for OS/400 C++ User’s Guide


Figure 9 (Page 3 of 3). Compiler Options Summary
Option Description Default Page
/Lx[+|-] Generate a minimal cross-reference table in the listing file /Lx- 107
/Ly[+|-] Generate a cross-reference table in the listing file /Ly- 108
/Nn End compilation when error count reaches n No limit. 108
/O[+|-|10|20|30|40] Optimize code /O- 118
/Oi[+|-] Inline specified user functions /Oi- 119
/Oivalue
/P[+|-] Run the preprocessor only, instead of a full compile /P- 115
/Pc[+|-] Preserve source code comments in preprocessor output /P- 115
/Pd[+|-] Redirect preprocessor output /P- 116
/Pe[+|-] Suppress #line directives in preprocessor output /P- 116
/Q[+|-] Display compiler logo when invoking the compiler /Q- 123
/S[a|c|e] Set the language level /Se 112
/Si[+|-][dir][name] Use precompiled header files, if they exist and are current /Si- 112
/Sn[+|-] Parse double-byte character set C++ source files /Sn- 113
/Sp[1|2|4|8|16] Specify alignment or packing of data items within structures and /Sp16 113
unions
/Su[+|-|1|2|4] Control size of enum variables, instead of using the SAA rules /Su- 114
/Ti[+|-|s|l|n] Generate debugger information /Ti- 108
/Tl[+|-|value] Control preloading of the compiler, instead of accepting the /Tl+ 123
default preloading behavior
/U<name|*> Undefine macros Retain macros 117
/V"string" Include a version string in the module and program or service /V"" 124
program objects
/W[0|1|2|3] Set severity level of messages the compiler produces and counts /W3 109
/Wgrp[+|-][grp] Generate or suppress messages in the grp group /Wall- 109
/Xc[+|-] Do not search paths specified using /I /Xc- 103
/Xi[+|-] Do not search paths specified in the INCLUDE_ASV3R6 and /Xi- 103
INCLUDE_ASV3R1 environment variables

Output File Management Options


Use the Output File Management options to control the files that the compiler
produces.

Examples of Output File Management Options


Ÿ Perform syntax check only:

Chapter 7. Setting Compiler Options 97


/ASl Option

iccas /Fc+ myprog.cpp


Ÿ Name the module object:
iccas /FoSTOCK myprog.cpp
This names the module object STOCK instead of the default, MYPROG.
Ÿ Name the listing file:
iccas /Floutput.my /L fred.cpp
This creates a listing output called output.my instead of fred.lst.

/ASd
i2 refid=i014.saving header files

Syntax: Default:
/ASd[+|-] /ASd+
/ASd[dir]

Use /ASd to save header files generated from the #pragma mapinc directive.

You can specify a directory of your choice through the /ASddir compiler option.
The header files will be saved relative to that directory.
Note: If the #pragma mapinc directive specifies a fully qualified name, the file will
be stored there, and not relative to the /ASd directory.

By default, the compiler saves header files relative to the current directory, in the
filename given on the #pragma mapinc directive.

See the VisualAge C++ for OS/400 C++ Programming Guide for a more detailed
discussion of #pragma mapinc.

/ASl

Syntax: Default:
/ASlname none

Use /ASlname to designate a target library for the module and program or service
program objects to be created. Specify this library as name.
Note: The target library name must be a valid AS/400 library name and cannot be
longer than 10 characters. If the library name contains invalid characters or is longer
than 10 characters, compilation of the source file is terminated with an error message

98 IBM VisualAge C++ for OS/400 C++ User’s Guide


indicating that the library name is invalid. See “File Naming Conventions” on
page 59 for a description of valid AS/400 names.

There is no default for ASl. If /ASlname is specified,this library is used. Otherwise,


the compiler probes the host for the current library. If no current library has been
specified, the compiler uses the library QGPL.

/ASr

Syntax Default
/ASr[+|-] /ASr+

Use /ASr to replace a module object.

By default, the compiler replaces the existing object.

/Fb

Syntax: Default:
/Fb[+|-|\] /Fb-

Use /Fb to produce a browser file. The file has the same name as the next source
file with the extension .pdb. The browser information generated excludes informa-
tion about system include files.

Use /Fb\ to generate browser information that includes information about system
include files.

By default, the compiler does not produce a browser file.

/Fc

Syntax: Default:
/Fc[+|-] /Fc-

Use /Fc to perform only a syntax check. The only output files you can produce
when this option is in effect are listing (.lst) files. This option is useful when you
compile in disconnected mode.

By default, the compiler performs a full compilation.

Chapter 7. Setting Compiler Options 99


/Fi

Syntax: Default:
/Fi[+|-] /Fi-

Use /Fi to control creation of precompiled header files. The compiler creates a pre-
compiled header file if none exists or if the existing one is not current.

By default, the compiler does not create a precompiled header file.

/Fl

Syntax: Default:
/Fl[+|-] /Fl-
/Fl[dir][name]

Use /Fl to produce, name, and direct a listing file. The listing file will be name.lst,
and will be placed in directory dir, for example:
iccas /Fl mydir/myname

The compiler produces a separate listing file for each source file that follows the
option on the OS/2 command line. The name you provide applies only to the first
listing file.

If you do not specify a name or directory, the listing takes the same file name as the
source file, with the extension .lst, and is put in the current directory.

If the directory you specify is not valid, the compiler does not generate a listing file:
it generates a warning message and the option does not take effect.

By default, the compiler does not produce a listing file.

/Fo

Syntax: Default:
/Fo[+|-] /Fo+
/Fo[name]

Use /Fo to produce and name a module object (\MODULE). The object will be called
name and will be placed in the current library on the AS/400. If you want to specify
a different library, use the /ASlname option. If the specified library is invalid, the
compiler will not create a module object.
100 IBM VisualAge C++ for OS/400 C++ User’s Guide
The compiler produces a separate module object for each source file that follows the
options on the OS/2 command line. The name you provide applies only to the first
module object.

By default, the compiler produces a module object with the same name as the source
file. This module object is created in library QGPL, if there is no current library.

Specify /Fo- if you do not want the compiler to create a module object.
Note: The module name must be a valid AS/400 object name. See “File
Naming Conventions” on page 59 for a description of valid AS/400 names. If the
module name is not specified, the source file name of the first file to be compiled is
used, which must be a valid AS/400 name. An invalid module name results in an
error message and the iccas invocation is terminated.

/Ft

Syntax: Default:
/Ft[+|-] /Ft+
/Ftdir

Use /Ft to control generation of files for template resolution.

Specify /Ft- to suppress generation of files for template resolution.

Specify /Ftdir to generate the files for templat e resolution and place them in the
dir directory.

By default, files for template resolution are generated and stored in the TEMPINC sub-
directory under the current directory.

/Fw

Syntax: Default:
/Fw[+|-] /Fw-
/Fw[dir][name]

Use /Fw to produce, name, and direct intermediate code files, without completing
compilation. The intermediate code file will be name.qwo, and will be placed in
directory dir.

Chapter 7. Setting Compiler Options 101


The compiler produces a separate intermediate code file for each source file that
follows the option on the OS/2 command line. The name you provide applies only to
the first intermediate code file.

If you do not specify a name, the intermediate code file takes the same file name as
the source file, with the extension .qwo.

If the directory you specify is not valid, the compiler does not save the intermediate
code file; it generates a warning message and the option does not take effect.

By default, the compiler performs regular compilation, without saving the interme-
diate code file.

#include File Search Options


Use these options to control which paths are searched when the compiler looks for
#include files. The paths that are searched are the result of the information in the
INCLUDE_ASV3R6, the INCLUDE_ASV3R1, and the ICCAS environment variables, com-
bined with the compiler options.

Using the #include File Search Options


The /I option must be followed by one or more directory names. A space may be
included between /I and the directory name. If you specify several directories, sepa-
rate the directory names with a semicolon.

If you use the /I option more than once, the directories you specify are appended to
the directories you previously specified. For example:
/Id:\hdr;e:\ /I f:\
is equivalent to
/Id:\hdr\;e:\;f:\

If you specify search paths using /I in both the ICCAS environment variable and on
the OS/2 command line, all the paths are searched. The paths specified in ICCAS are
searched before those specified on the OS/2 command line.

Attention: Once you use the /Xc option, the paths previously specified by using /I
cannot be recovered. You have to use the /I option again if you want to reuse the
paths canceled by /Xc.

The /Xi option has no effect on the /Xc and /I options. See “Controlling
#include Search Paths” on page 66 for further information on #include files and
search paths.

102 IBM VisualAge C++ for OS/400 C++ User’s Guide


/I

Syntax: Default:
/Ipath[;path] Directory of source file, paths in
INCLUDE_ASV3R6 and INCLUDE_ASV3R1
environment variables

Use /I to specify #include search path(s). The compiler will search path[;path].
Note that the directory of the source file is always searched first for user include files.

By default, the compiler searches the directory of the source file (for user files only),
and then the search paths given in the INCLUDE_ASV3R6 and INCLUDE_ASV3R1 envi-
ronment variables.

/Xc

Syntax: Default:
/Xc[+|-] /Xc-

Use /Xc to stop the compiler from searching paths specified using /I.

By default, the compiler searches paths specified using /I.

/Xi

Syntax: Default:
/Xi[+|-] /Xi-

Use /Xi to stop the compiler from searching paths specified by the INCLUDE_ASV3R6
and INCLUDE_ASV3R1 environment variables.

By default, the compiler searches paths specified in the INCLUDE_ASV3R6 and


INCLUDE_ASV3R1 environment variables.

Listing File Options


The options listed below control whether or not a listing file is produced, the type of
information in the listing, and the appearance of the file.
Note: The following options only modify the appearance of a listing; they do not
produce a listing. Use them with one of the other listing file options, or the /Fl
option, to produce a listing:

Chapter 7. Setting Compiler Options 103


La- /Lb- /Le /Li /Lj /Lp /Lt /Lu

If you specify any of the /Le, /Li, or /Lj options, you must also specify the /L,
/Lf, or /Ls option.

Including Information about Your Source Program


You can use three options to include information about your source program in the
listing file:
/Ls+ Includes the source program in the listing file.
/Li+ Shows the included text after the user #include directives.
/Lj+ Shows the included text after both user and system #include direc-
tives.
Note: If you specify the /Lj option, /Li+ and /Li- have no effect.

Including Information about Variables


The options that produce information about the variables used in your program
provide the following amount of detail:
/La+ Includes a table of all the referenced struct and union variables in
the source program.
/Lb+ Includes a table of all struct and union variables in the program.
/Le+ Includes all expanded macros in the listing file.
/Lx+ Includes a cross-reference table that contains a list of the referenced
identifiers in the source file together with the numbers of the lines
on which they appear.
/Ly+ Includes a cross-reference table that contains a list of all identifiers
referenced by the user and all external identifiers, together with the
numbers of the lines on which they appear.

/L

Syntax: Default:
/L[+|-] /L-

Use /L to produce a listing file. The listing file contains only a prolog and error
messages. You can modify the contents of the listing using other listing file options.

By default, the compiler does not produce a listing file.

104 IBM VisualAge C++ for OS/400 C++ User’s Guide


/La

Syntax: Default:
/La[+|-] /La-

Use /La to include a table in the listing file that shows all the referenced struct and
union variables in the source program. The table shows how each structure and
union in the program is mapped. It contains the following information:
Ÿ The name of the structure or union and the elements within each.
Ÿ The byte offset of each element from the beginning of the structure or union.
The bit offset for unaligned bit data is also given.
Ÿ The length of each element.
Ÿ The total length of each structure, union, and substructure in both packed and
unpacked formats.

By default, the listing does not include a layout.

/Lb

Syntax: Default:
/Lb[+|-] /Lb-

Use /Lb to include a table in the listing file that shows all the struct and union
variables in the source program. The table shows how each structure and union in
the program is mapped. It contains the following information:
Ÿ The name of the structure or union and the elements within each.
Ÿ The byte offset of each element from the beginning of the structure or union.
The bit offset for unaligned bit data is also given.
Ÿ The length of each element.
Ÿ The total length of each structure, union, and substructure in both packed and
unpacked formats.

By default, the listing does not include a layout.

/Le

Syntax: Default:
/Le[+|-] /Le-

Chapter 7. Setting Compiler Options 105


Use /Le to expand all macros in the listing file.

By default, the listing does not show macros expanded.

/Lf

Syntax: Default:
/Lf[+|-] /Lf-

Use /Lf to set all listing options on.

By default, all listing options are off.

/Li

Syntax: Default:
/Li[+|-] /Li-

Use /Li to expand user #include files in the listing file.

By default, the listing does not show user #include files expanded.

/Lj
INCLUDE_ASV3R1

Syntax: Default:
/Lj[+|-] /Lj-

Use /Lj to expand user and system #include files in the listing file.

If you use HPFS and have very long file names, there may not be enough room for
the file names on the lines showing the included code. Counters are used in the
INCLUDE column of the listing output, and the file name that corresponds to each
number is given at the bottom of the source listing.

By default, the listing does not show user and system #include files expanded.

/Lp

Syntax: Default:
/Lpnum /Lp66

106 IBM VisualAge C++ for OS/400 C++ User’s Guide


Use /Lp to set the page length of the listing. Each page will be num lines long. num
must be between 15 and 65535 inclusive.

By default, the listing has 66 lines per page.

/Ls

Syntax: Default:
/Ls[+|-] /Ls-

Use /Ls to include the source code in the listing file.

By default, the listing does not include the source code.

/Lt

Syntax: Default:
/Lt"string" Use name of source file

Use /Lt to set the title string of the listing file to string. Maximum string length is
256 characters.

By default, the title string is set to the name of the source file.

/Lu

Syntax: Default:
/Lu"string" /Lu""

Use /Lu to set the subtitle string in the listing file to string. Maximum string length
is 256 characters.

By default, no subtitle is set (null string).

/Lx

Syntax: Default:
/Lx[+|-] /Lx-

Use /Lx to generate a cross-reference table of referenced variable, structure, and func-
tion names. The table shows line numbers where names are declared.

Chapter 7. Setting Compiler Options 107


By default, the listing does not include the cross-reference table.

/Ly

Syntax: Default:
/Ly[+|-] /Ly-

Use /Ly to generate a cross-reference table of all variable, structure, and function
names, plus all local variables referenced by the user. The table shows line numbers
where names are declared.

By default, the listing does not include the cross-reference table.

Debugging and Diagnostic Information Options


The options listed here are useful for debugging your programs.

Use /Wgrp to control what types of diagnostic messages are produced.


Note: The information generated by the debugger and /Wgrp options is provided to
diagnose problems in your code. Do not use the diagnostic information as a
programming interface.

/N

Syntax: Default:
/Nn No limit

Use /N to set the maximum number of error messages before compilation is termi-
nated. Compilation ends when the error count reaches n.

By default, the compiler does not set a limit on the number of errors.

/Ti

Syntax: Default:
/Ti[+|-|l|n|s] /Ti-

Use /Ti to enable all options to debug the program and produce a listing view. This
option is the equivalent of the AS/400 DBGVIEW(*ALL) parameter.

108 IBM VisualAge C++ for OS/400 C++ User’s Guide


Use /Til to generate a listing view to debug the program. This option is the equiv-
alent of the AS/400 DBGVIEW(*LIST) parameter.

Use /Tin to generate debug data without creating a listing or a source view. This
option allows the program to be debugged using symbolic identifiers. It is the equiv-
alent of the AS/400 DBGVIEW(*STMT) parameter.

Use /Tis to generate a source view for debugging the program. This option is the
equivalent of the AS/400 DBGVIEW(*SOURCE) parameter.

By default, the compiler does not generate debug information.

Recommendations:
If you use the /Ti option to generate debugger information, it is recommended that
you turn optimization off (/O-).

Because of the effects of optimization, debugging information generated with opti-


mization is limited to setting breakpoints at function entry and function exit. Accu-
rate symbol and type information is not always available.

/W

Syntax: Default:
/W[ð|1|2|3] /W3

Use /W to set the severity level of message the compiler produces and that causes the
error count to increment.

By default (/W3)), the compiler produces and counts all message types (severe error,
error, warning, and informational).

You can set the following severity levels:


/Wð Produce and count only severe errors.
/W1 Produce and count severe errors and errors.
/W2 Produce and count severe errors, errors, and warnings.
/W3 Produce and count all message types (severe error, error, warning, and informa-
tional.

/Wgrp

Chapter 7. Setting Compiler Options 109


Syntax: Default:
/Wgrp[+|-] [grp] /Wall-

Use /Wgrp to generate messages in the grp group. You can specify more than one
group.

By default, the compiler suppresses all informational messages.

The /Wgrp options control informational messages that warn of possible programming
errors, weak programming style, and other information about the structure of your
programs. Similar messages are in groups, or suboptions, to give you greater control
over which types of messages you want to generate.

When you specify /Wall[+], all suboptions are turned on and all possible diagnostic
messages are reported. Because even a simple program that contains no errors can
produce many messages, you may not want to use /Wall very often. You can use
the suboptions alone or in combination to specify the type of messages that you want
the compiler to report. Suboptions can be separated by an optional + sign. To turn
off a suboption, you must place a - sign after it.

You can also combine the /W[ð|1|2|3] options with the /Wgrp options.

The following table lists the message groups and the message numbers that each con-
trols.

Figure 10 (Page 1 of 2). /Wgrp Options

grp Controls Messages About Messages


all All diagnostics All message numbers listed in this table
cls Use of classes CTT3110, CTT3253, CTT3266
cmp Possible redundancies in unsigned compar- CTT3138, CTT3139, CTT3140
isons
cnd Possible redundancies or problems in condi- CTT3107, CTT3130
tional expressions
cns Operations involving constants CTT3131, CTT3219
cnv Conversions CTT3313
cpy Problems generating copy constructors CTT3199, CTT3200
eff Statements without effect CTT3165, CTT3215
enu Consistency of enum variables CTT3137
ext Unused external definitions CTT3127

110 IBM VisualAge C++ for OS/400 C++ User’s Guide


Figure 10 (Page 2 of 2). /Wgrp Options

grp Controls Messages About Messages


gen General diagnostics CTT3101
gnr Generation of temporary variables CTT3151
lan Effects of the language level CTT3116
par Unused parameters CTT3126
por Nonportable language constructs CTT3132, CTT3133, CTT3135, CTT3136
ppc Possible problems with using the pre- CTT3645
processor
rea Code that cannot be reached CTT3119
trd Possible truncation or loss of data or preci- CTT3108, CTT3135, CTT3136
sion
und Casting of pointers to or from an undefined CTT3098
class
use Unused auto and static variables CTT3002, CTT3099, CTT3100
vft Generation of virtual function tables CTT3280, CTT3281, CTT3282

Examples of /Wgrp Options


Ÿ Produce all diagnostic messages:
iccas /Wall blue.cpp
iccas /Wall+ blue.cpp
Ÿ Produce diagnostic messages about:
– Unreferenced parameters
– Missing function prototypes
– Uninitialized variables
by turning on the appropriate suboptions:
iccas /Wpar+por+uni blue.cpp
iccas /Wparporuni blue.cpp
Ÿ Produce all diagnostic messages except:
– Warnings about assignments that can cause a loss of precision
– Preprocessor trace messages
– External variable warnings
by turning on all options, and then turning off the ones you do not want:
iccas /Wall+trd-ppt-ext- blue.cpp

Chapter 7. Setting Compiler Options 111


Ÿ Produce only basic diagnostics, with all other suboptions turned off:
iccas /Wgen+ blue.cpp
Ÿ Produce only basic diagnostics and messages about severe errors, errors, or
warnings (/W2):
iccas /Wgen2 blue.cpp

Source Code Options


The following options control how the IBM VisualAge C++ for OS/400 compiler
interprets your source file:

/S /Si /Sn /Sp /Su

This control is especially useful, for example, if you are migrating code or ensuring
consistency with a particular language standard.

/S

Syntax: Default:
/S[a|c|e] /Se

Use /S to set the language level.

You can set the following language levels:


/Sa Conform to ANSI standards.
/Sc Allow constructs compatible with older levels of the C++ language.
/Se Allow all VisualAge C++ for OS/400 language constructs

By default, the compiler allows all IBM VisualAge C++ for OS/400 language exten-
sions.

See “Setting the Source Code Language Level” on page 70 for details.

/Si

Syntax: Default:
/Si[+|-]
/Si[dir][name] /Si-

Use /Si to use precompiled header files, if they exist and are current.

112 IBM VisualAge C++ for OS/400 C++ User’s Guide


If you specify a name or directory with the option, the compiler looks for a precom-
piled header file with the name and in the directory you specify.

Use the /Fi option to create or update precompiled header files. Use /Si and /Fi in
combination to ensure that precompiled header files are always up to date.
Note: The file you generate (/Fi) must be the same file you use (/Si). If you
specify different file names or directories with the same options, the name or direc-
tory specified last is used with both options.

See “Precompiled Header Files” on page 79 for more information, such as


location, time stamp, search path, and restrictions when working with precompiled
header files.

By default, the compiler does not use precompiled header files.

/Sn

Syntax: Default:
/Sn[+|-] /Sn-

Use /Sn to parse double-byte character set C++ source files.

By default, the compiler parses C++ source files as single-byte character set files.

See VisualAge C++ for OS/400 Read Me First! for more information on compiling
double-byte character-set C++ files.

/Sp

Syntax: Default:
/Sp[1|2|4|8|16] /Sp16

Use /Sp to specify alignment or packing of data items within structures and unions.

By default, structures and unions are aligned along 16-byte boundaries (normal align-
ment).

You can align structures and unions along 1-byte, 2-byte, 4-byte, 8-byte, or 16-byte
boundaries. /Sp is equivalent to /Sp1.
Note: Pointer members of a structure always align at the 16-byte boundary.

Chapter 7. Setting Compiler Options 113


/Su

Syntax: Default:
/Su[+|-|1|2|4] /Su-

Use /Su to control the size of enum variables. If you do not provide a size, all enum
variables are made 4 bytes.

By default, the compiler makes all enum variables the size of the smallest integral
type that can contain all variables.

You can specify the following sizes:


/Su+ Make all enum variables 4 bytes.
/Su1 Make all enum variables 1 byte.
/Su2 Make all enum variables 2 bytes.
/Su4 Make all enum variables 4 bytes.

Preprocessor Options
The options listed control the use of the preprocessor:

/D /P /Pc /Pd /Pe /U

Note that the /Pc, /Pd, and /Pe options are actually suboptions of /P. Specifying
/Pc- is the same as specifying /P+c-, and only the preprocessor is run.

Using the Preprocessor


Preprocessor directives, such as #include, allow you to include C++ code from
another source file into yours, to define macros, and to expand macros.

See the VisualAge C++ for OS/400 C++ Language Reference for a list of pre-
processor directives and information on how to use them.

If you run only the preprocessor, you can use the preprocessor output to debug a
program. All the preprocessor directives have been executed, but no code has been
compiled. For example, all macros are expanded, and the code of all files included
by #include directives appears in your program.

By default, comments in the source code are not included in the preprocessor output.
To preserve the comments, use the /Pc option.

114 IBM VisualAge C++ for OS/400 C++ User’s Guide


The /P, /Pc, /Pd, and /Pe options can be used in combination with each other. For
example, to preserve comments, suppress #line directives, and redirect the pre-
processor output to stdout, specify /Pcde.

/D

Syntax: Default:
/Dname[::n] Do not define macros on the OS/2
command line.
/Dname[=n]

Use /D to define preprocessor macro name to the value n. If n is omitted, the macro
is set to a null string. Macros defined on the OS/2 command line override macros
defined in the source code.

By default, no macros are defined on the OS/2 command line.

/P

Syntax: Default:
/P[+|-] /P-

Use /P to run the preprocessor only, and create a preprocessor output file that has the
same name as the source file, with the extension .i.

By default, both the preprocessor and the compiler run, and preprocessor output is not
generated.

/Pc

Syntax: Default:
/Pc[+|-] /P-

Use /Pc to run the preprocessor only, and control the inclusion of comments in the
preprocessor output.

Specify /Pc[+] to run the preprocessor only, and create a preprocessor output file
that includes the comments from the source code. The output file has the same name
as the source file, with the extension .i.

Chapter 7. Setting Compiler Options 115


Specify /Pc- to run the preprocessor only, and create a preprocessor output file with
the comments stripped out. The output file has the same name as the source file,
with the extension .i.

By default, both the compiler and preprocessor run, and preprocessor output is not
generated.

/Pd

Syntax: Default:
/Pd[+|-] /P-

Use /Pd to run the preprocessor only, and control redirection of the preprocessor
output.

Specify /Pd+ to run the preprocessor only, and send the preprocessor output to
stdout.

Specify /Pd- to run the preprocessor only, and not redirect preprocessor output. Pre-
processor output is written to a file that has the same name as the source file, with
the extension .I

By default, both the compiler and preprocessor run, and preprocessor output is not
generated.

/Pe

Syntax: Default:
/Pe[+|-] /P-

Use /Pe to run the preprocessor only, and control the creation of #line directives in
the preprocessor output.

Specify /Pe+ to run the preprocessor only, and suppress creation of #line directives
in the preprocessor output. The output file has the same name as the source file, with
the extension .i.

Specify /Pe- to run the preprocessor only, and generate #line directives in the pre-
processor output. The output file has the same name as the source file, with the
extension .i.

By default, both the compiler and preprocessor run, and preprocessor output is not
generated.

116 IBM VisualAge C++ for OS/400 C++ User’s Guide


/U

Syntax: Default:
/U<name|> Retain macros.

Use /U to undefine macros.

Specify /Uname to undefine macro name.

Specify /U\ to undefine all macros.


Note: /U does not affect the macro __FUNCTION, nor does it undefine macros
defined in source code.

By default, the preprocessor retains all macros.

Code Generation Options


The following options specify how the code produced by the compiler is optimized
and if functions are inlined:

/ASi /ASp /O /Oi

Notes:
1. The /Oi+ option is more effective when /O+ is also specified.
2. Using optimization (/O+) limits the use of the debugger. The /Ti option is not
recommended for use with optimization.

/ASi

Syntax: Default:
/ASi[+|-] /ASi+

Use /ASi to generate code that uses integrated file system APIs.

You can alternatively use /D__IFS_IO__.

By default, the compiler uses integrated file system functions defined in stdio.h.
(This option has no effect on iostream.h.)
Note: When you compile with /ASi,the hexadecimal value of \n is 25. When you
compile with /ASi-, the hexadecimal value of \n is 15.

Chapter 7. Setting Compiler Options 117


See the VisualAge C++ for OS/400 C++ Programming Guide for details on the
Integrated File System..

/ASp

Syntax: Default:
/ASp[-|1|2a|2n|3a|3n] /ASp1

Use /ASp to control the generation of performance-data collection code

Use /ASp- to not generate performance-data collection code.

Use /ASp1 to generate performance-data-collection code at entry to and exit from the
program entry procedure only.

Use /ASp2a to generate performance-data-collection code at entry to and exit from all
the procedures in the program.

Use /ASp2n to generate performance-data-collection code at entry to and exit from


non-leaf procedures only.

Use /ASp3a to generate performance-data-collection code at procedure entry/exit and


before and after calls to external procedures, for all procedures in the program.

Use /ASp3n to generate performance-data-collection code at procedure entry/exit and


before and after calls to external procedures, for non-leaf procedures only.

By default, the compiler generates performance-data-collection code at entry to and


exit from the program entry procedure only.

/O

Syntax: Default:
/O[+|-|1ð|2ð|3ð|4ð] /O-

Use /O to control the optimization of your code.


Note: Do not optimize code if you want to use debugging or diagnostic options.

Use /O2ð to set basic optimization on.

Use O+ or /O3ð to set full optimization on.

118 IBM VisualAge C++ for OS/400 C++ User’s Guide


Use /O4ð to set super optimization (level 40) on.

By default, the code is not optimized. /O- and /O1ð are equivalent.

/Oi

Syntax: Default:
/Oi[+|-] /Oi-
/Oivalue

Use /Oi to control inlining of user code.

By default, no user code is inlined. When /O[+|1|2] is specified, /Oi+ becomes the
default.

You can specify the following types of inlining:


/Oi+ Inline all user functions qualified with the inline keyword.
/Oi- Do not inline any user code.
/Oivalue Inline all user functions qualified with the inline keyword or that are
smaller than value in abstract code units.

See “Inlining User Code” on page 81 for more information.

Other Options
Use the following options to control binder parameters, logo display, default char
type, and other IBM VisualAge C++ for OS/400 options:

/? /ASa /AScp /ASn /ASt /ASv3r1 /B /C /J /Q /Tl /V

Examples of Other Options


Ÿ Passing a parameter to the binder:
iccas /B"crtsrvpgm a" file1.cpp file2.cpp
The /B"crtsrvpgm a" option tells the compiler to compile the source files file1
and file2 and create a service program A on the host system.
Ÿ Imbedding a version string or copyright:
iccas /V"Version 1.ð" myfile.cpp
This imbeds the version notice in the module and program objects MYFILE.

Chapter 7. Setting Compiler Options 119


/?

Syntax: Default:
/? None

Use /? to display a list of compiler options with descriptions.

/ASa

Syntax: Default:
/ASa[l|c|u|a|e|"list-name"] /ASal

Use /ASa to specify the module and program authority granted to users who do not
have specific authority.

Use /ASac to provide all data authority and the authority to perform all operations on
the module object, except those limited to the owner or controlled by object authority
and object management authority. The module object can be changed and basic func-
tions can be performed on it. This option is the equivalent of the *CHANGE param-
eter on the AS/400 Create Module command.

Use /ASau to provide object operational authority; read authority; and authority to
perform basic operations on the module object such as binding the module object.
Users without specific authority are prevented from changing the module object. This
option is the equivalent of the *USE parameter on the AS/400 Create Module
command.

Use /ASaa to provide authority to perform all operations on the module object, except
those limited to the owner or controlled by authorization list management authority.
Any user can control the module object's existence, specify the security for it, change
it, and perform basic functions on it, but cannot transfer ownership of the object.
This option is the equivalent of the *ALL parameter on the AS/400 Create Module
command.

Use /ASae to ensure that users without special authority cannot access the module
object. This option is the equivalent of the *EXCLUDE parameter on the AS/400
Create Module command.

Use /ASa"list-name" to specify the name of an authorization list of users and


authorities to which the module object is added. The module object is secured by this
authorization list, and the public authority for the module object is set to *AUTL.
The authorization list must exist on the system when this option is specified.

120 IBM VisualAge C++ for OS/400 C++ User’s Guide


By default, the compiler takes the authority for the module object to be created from
the CRTAUT keyword of the target library (the library that contains the created module
object, on AS/400). This option is the equivalent of the *LIBCRTAUT parameter on
the AS/400 Create Module command.

/AScp

Syntax: Default:
/AScp[n] /AScp37

Use /AScp[n] to specify the coded character set ID (CCSID) for the destination
AS/400 system. n represents the code page number.

See the VisualAge C++ for OS/400 Read Me First! for a list of CCSIDs the com-
piler supports.

By default, the compiler uses the CCSID of the job running on the AS/400 identified
by the ICCASNAME environment variable, when running in connected mode. When
running in disconnected mode, the compiler uses CCSID 37 (US English).

When a CCSID is specified in several places, the precedence rules are as follows:
1. CCSID specified on the /AScp compiler option
2. CCSID specified on the ICCASCP environment variable
3. AS/400 CCSID (none if you compile in disconnected mode)

/ASn

Syntax: Default:
/ASnname Value of ICCASNAME

Use /ASnname to specify the name of the connection to the host system of your
choice.

If you have specified the name of the connection in the ICCASNAME environment
variable, the ASnname option is not necessary. Otherwise it will override the name
specified in ICCASNAME.

By default, the compiler uses the name specified in the ICCASNAME variable. If
ICCASNAME is not set, the compiler issues an error message.

Chapter 7. Setting Compiler Options 121


/ASt

Syntax: Default:
/ASttext Blanks

Use /ASttext to specify a text description for the module object. If necessary, the
text is truncated to 50 characters. The compiler issues a warning if truncation occurs.

By default, the compiler inserts blank spaces in the text string.

/ASv3r1

Syntax: Default:
/ASv3r1[+|-] /ASv3r1-

Use /ASv3r1 to compile source files into program or service program objects that
will run in a V3R1 IMPI environment.

By default, the compiler targets the V3R6 RISC run-time environment.

/B

Syntax: Default:
/B"binding command" /B"crtpgm pgm(xxx/yyy) " with default
options of the CRTPGM host command

Use /B to pass the binding command string to the binder.

By default, /B"crtpgm PGM (xxx/xxx)" is passed to the binder xxxand yyy are filled
in with the appropriate library and program name by the iccas compiler invocation
command.

If you specify the /B option, you must specify either "crtpgm pgm
(library-name/program-name)", or "crtsrvpgm srvpgm
(library-name/srvprogram-name)", The string may also contain additional binding
options, eg."actgrp(abc)"

See Chapter 8, “Creating an OS/400 Program” on page 127 and Chapter 9, “Cre-
ating a Service Program” on page 141 for information on binding module objects into
programs and service programs from the workstation.

122 IBM VisualAge C++ for OS/400 C++ User’s Guide


/C

Syntax: Default:
/C[+|-] /C-

Use /C to perform a compile only, without binding. This option results in the cre-
ation of a module object (\MODULE)

By default, code is both compiled and bound into a program object (\PGM).

If you want to create a service program (\SRVPGM), you must also specify the
/B"crtsrvpgm srvpgm(library-name/service-program-name)" option.

/J

Syntax: Default:
/J[+|-] /J+

Use /J- to set unspecified char variables to signed char.

By default unspecified char variables are set to unsigned char.

/Q

Syntax: Default:
/Q[+|-] /Q-

Use /Q+ to suppress the compiler logo that appears when you invoke the compiler.

By default, the compiler logo appears on stderr.

/Tl

Syntax: Default:
/Tl[+|-|value] /Tl+

Use /Tl to control preloading of the compiler.

By default, each compiler component is preloaded as required, and kept in memory


for ten minutes from the time it was last referenced.

Chapter 7. Setting Compiler Options 123


You can set the following preloading options:
/Tl[+] Preload the compiler components as required. A component remains in
memory for 10 minutes. If it is referenced in that time, the timer starts
again. Each compiler component has its own timer.
/Tl- Do not preload the compiler. You can specify this option without a file
name to unload any components that are loaded.
/Tlvalue Preload the compiler components as required and keep the files in
memory for value minutes.

/V

Syntax: Default:
/V"string" /V""

Use /V to include a version string in the object and executable files. The version
string is set to string. The length of the string can be up to 256 characters.

By default, no version string is set.

124 IBM VisualAge C++ for OS/400 C++ User’s Guide


Part 3. Binding and Running Your Program
Binding and running an ILE C++ application requires a series of steps described in
the following chapters. The main topics include:
Ÿ Creating Programs
Ÿ Creating Service Programs
Ÿ Working With Exports From Service Programs
Ÿ Creating a Make File
Ÿ Running an Application

 Copyright IBM Corp. 1995 125


126 IBM VisualAge C++ for OS/400 C++ User’s Guide
Binding Modules into Programs

8 Creating an OS/400 Program

You create an OS/400 program by binding one or more module objects into a
program object.

The previous chapters discussed how to compile source code into module objects.
Topics in this chapter cover:
Ÿ Binding modules into programs
Ÿ Invoking CL commands from an OS/2 workstation
Ÿ Invoking the binder to create a program
Ÿ Changing a module or a program after it has been created

The next chapter, Chapter 9, “Creating a Service Program” on page 141, contains
details on binding module objects into service programs.

Binding Modules into Programs


In the AS/400 Integrated Language Environment, creating a program consists of com-
piling each source-code file into a module object (\MODULE), and then binding either
one or multiple module objects into a program object (\PGM).

The creation of permanent modules allows you to modularize an application, and


make changes to individual modules without having to recompile the whole applica-
tion. The same module can be reused in different applications.

Binding is the process of combining one or multiple modules and optional service
programs, and resolving symbols passed between them. The system code that com-
bines modules and resolves symbols is called the binder.

While the compilation of source code into module objects takes place on both the
OS/2 workstation and an AS/400, binding takes place on the AS/400 only, although
you may invoke the binder from the workstation.

Program and User Entry Procedures


As part of the binding process, a procedure must be identified as the startup proce-
dure, or program entry procedure (PEP). When a program is called, the PEP
receives the command line parameters and is given initial control for the program.
The procedures that get control from the PEP are called user entry procedures
(UEPs).

 Copyright IBM Corp. 1995 127


Binding Modules into Programs

An ILE C++ module contains a program entry procedure only if it contains a main()
function. Therefore, one of the modules being bound into the program must contain a
main() function.
Note: The same may not be true of other ILE languages. For example, each ILE
RPG/400 module implicitly contains a program entry procedure.

Internal Structure of a Program Object


Figure 11 shows the internal structure of a typical program object, MYPROG, created
by binding two modules, TRNSRPT and INCALC. In this example, TRNSRPT is the entry
module containing the PEP, in addition to a UEP. Module INCALC contains a UEP
only.

MYPROG(*PGM)
TRNSRPT Module

Program Entry Procedure

User Entry Procedure

INCALC Module

User Entry Procedure

Figure 11. Structure of Program MYPROG

Static Procedure Calls


Within a bound object, procedures can be called using static procedure calls. These
bound calls are faster than external calls. Therefore, an application consisting of a
single bound program with many bound calls should perform faster than a similar
application consisting of separate programs with many external inter-program calls.

128 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking CL Commands from OS/2

Service Programs
In addition to binding several modules together, you can also bind modules to service
programs (type \SRVPGM) when creating program objects.

Common routines may be created as service programs, and if the routine changes, the
change can be incorporated by binding the service program again. The programs that
use these common routines do not have to be recreated.

See Chapter 9, “Creating a Service Program” on page 141 for information on


creating service programs.

Binding Directories
A binding directory contains the names of the modules and service programs that
you may need when creating an ILE program or service program.
Note: Modules or service programs listed in a binding directory are used only if
they provide an export that can satisfy any currently unresolved import requests.
Entries in the binding directory may refer to objects that do not yet exist at the time
the binding directory is created, but will exist later.

Binding directories are optional. They are objects identified to the system by the
*BNDDIR parameter on the CRTPGM command.

See ILE Concepts for more information on the binding process, the binder, and
binding directories, as well as for a list of related CL commands.

Invoking CL Commands from OS/2 through CTTHCMD


The following CL commands can be used with program objects:
Ÿ Create Program (CRTPGM)
Ÿ Change Program (CHGPGM)
Ÿ Delete Program (DLTPGM)
Ÿ Display Program (DSPPGM)
Ÿ Display Program References (DSPPGMREF)
Ÿ Update Program (UPDPGM)
Ÿ Work with Program (WRKPGM)

The workstation command CTTHCMD lets you issue these, and other, CL commands
directly from the workstation, provided you have established a host connection.

See “Issuing AS/400 CL Commands from the OS/2 Workstation” on page 45 for
details on the syntax and parameters of the CTTHCMD.

Chapter 8. Creating an OS/400 Program 129


Invoking the Binder to Create a Program

The CL Reference contains further information on all CL commands and their


parameters.

Invoking the Binder to Create a Program


The binder is invoked through the Create Program (CTRPGM) command. This
command creates a program object from one or more module objects and, if required,
one or more service programs.

You can bind modules created by iccas with modules created by any of the other
ILE Create Module commands, including CRTRPGMOD, CRTCMOD,
CRTCBLMOD, or CRTCLMOD.
Note: The modules or service programs to be bound must already have been created.

Parameters for the CRTPGM Command


Figure 12 lists CRTPGM command parameters and their default values.

See the CL Reference, for a full description of the CRTPGM command and its
parameters.

Figure 12. Parameters for CRTPGM Command and their Default Values

Parameter Group Parameter(Default Value)


Identification PGM(library name/program name)
MODULE(*PGM)
Program access ENTMOD(*FIRST)
Binding BNDSRVPGM(*NONE)
BNDDIR(*NONE)
Run time ACTGRP(*NEW)
Miscellaneous OPTION(*GEN *NODUPPROC *NODUPVAR *WARN
*RSLVREF)
DETAIL(*NONE)
ALWUPD(*YES)
ALWRINZ(*NO)
REPLACE(*YES)
AUT(*LIBCRTAUT)
TEXT(*ENTMODTXT)
TGTRLS(*CURRENT)
USRPRF(*USER)

130 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking the Binder to Create a Program

Before Issuing the CRTPGM Command


Before you create a program object using the CRTPGM command, you should:
1. Establish a program name.
2. Identify the module(s) and, if required, the service programs you want to bind
into a program object.
3. Make sure that the program has a program entry procedure that gets control when
a dynamic program call is made. (That is, one module must contain the main()
function of the program.)
You indicate which module contains the program entry procedure through the
ENTMOD parameter. The default is ENTMOD(*FIRST), which means that the
module containing the first program entry procedure found in the list for the
MODULE parameter is the entry module.
If you are binding more than one ILE C++ module together, you should specify
ENTMOD(*FIRST) or else specify the module name with the program entry proce-
dure. You can use ENTMOD(*ONLY) when you are binding only one module into
a program object, or if you are binding several modules but only one contains a
program entry procedure. For example, if you bind a C++ module with a main()
function to a C module without a main() function, you can specify
ENTMOD(*ONLY).
4. Identify the activation group that the program is to use.
Specify ACTGRP(*NEW) if your program has no special requirements or if you are
not sure which group to use.
Note that ACTGRP(*NEW) is the default activation group for CRTPGM. This
means that your program will run in its own activation group, and the activation
group will terminate once the program terminates. This default ensures that your
program has a refresh of the resources necessary to run, every time you call it.
See “Specifying an Activation Group” on page 189 for more information on
unnamed and named activation groups.

How to Issue the CRTPGM Command


Although the binding process always takes place on the AS/400, you may invoke the
binder either from your workstation or from the AS/400 host system. You may
choose one of the following four invocation methods:
1. From the WorkFrame environment, select the BIND action and invoke CRTPGM.
2. Invoke the compiler from an OS/2 command line and use the default option /B.
on the iccas compiler invocation command
3. Issue the CTTHCMD command from an OS/2 command line, and specify the
CRTPGM parameter

Chapter 8. Creating an OS/400 Program 131


Invoking the Binder to Create a Program

4. Issue the CRTPGM command from an AS/400 command line

Invoking CRTPGM from the WorkFrame Environment


If you have already created a project that contains all the files for the application
you are working on, see “Creating Programs and Service Programs” on page 24 for
details on how to invoke the Bind action.

If you have not yet created a project for your application and need help, see
Part 1, “Developing OS/400 Applications with WorkFrame” on page 1 first.

Invoking CRTPGM through the /B Compiler Option


When you invoke the compiler from the OS/2 command line through the iccas
command using default compiler options, creation of a program object is attempted on
the AS/400 (if you had established an AS/400 connection before invoking the com-
piler). For example, iccas myprog.cpp is equivalent to specifying
CRTPGM PGM(MYLIB/MYPROG) MODULE(MYPROG)
on an AS/400 command line, where MYLIB is the current library. (If there is no
current library, QGPL is used.)

This invocation results in the creation of a program MYPROG on the AS/400, using
default parameters on the CRTPGM command.

However, you may prefer to specify parameters of your choice. You can do so
through the /B compiler option, which passes binding commands and binding options
to the host.

For example:
iccas /B"crtpgm pgm(mylib/abc) actgrp(xyz)" abc.cpp def.cpp
results first in the creation of the module objects ABC and DEF, and then the command
CRTPGM PGM(MYLIB/ABC) ACTGRP(XYZ) MODULE(MYLIB/ABC MYLIB/DEF)
is passed to the AS/400, where the program object ABC is created in library MYLIB,
from the modules ABC and DEF located in the current library. The program will run
in the activation group XYZ, as specified.

If you want to bind a module to be created to a module object that already exists, you
do not need to recompile the source code for the existing module. For example, if
module object DEF already exists in MYLIB, the command:
iccas /B"crtpgm mylib/abc" abc.cpp def
results first in the creation of the module object ABC. Next, the command
CRTPGM PGM(MYLIB/ABC) MODULE(MYLIB/ABC MYLIB/DEF)

132 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking the Binder to Create a Program

is passed to the AS/400, where the program object ABC is created in library MYLIB,
from the modules ABC and DEF.

To bind two module objects ABC and DEF located in library MYLIB, invoke the com-
piler as follows:
iccas /B"crtpgm mylib/abc" abc def
results first in the creation of the module object ABC. Next, the command
CRTPGM PGM(MYLIB/ABC) MODULE(MYLIB/ABC MYLIB/DEF)
which passes the command
CRTPGM PGM(MYLIB/ABC) MODULE(MYLIB/ABC MYLIB/DEF)
to the AS/400, where the program object ABC is created in library MYLIB, from the
modules ABC and DEF.

You can also bind modules located in different libraries. For example
iccas /B"crtpgm mylib/mainpgm" /ASlmyl mainpgm.cpp /ASlmyrpg
rpgmod1 /ASlmycobol cblmod2
which results first in the creation of the module object MAINPGM in library MYL. Next,
the command
CRTPGM MYLIB/MAINPGM MODULE(MYL/MAINPGM
MYRPG/RPGMOD1 MYCOBOL/CBLMOD2)
is passed to the AS/400, where the program object MAINPGM is created in library
MYLIB, from the modules RPGMOD1 and CBLMOD2.

Invoking CRTPGM through the CTTHCMD Command


The CTTHCMD allows you to send a CL command to the AS/400 directly from your
workstation. If you want to use this interface to send the binding command, follow
the syntax:
CTTHCMD /ASnname hostcommand
or
@filename

as explained in “Invoking CL Commands from OS/2 through CTTHCMD” on


page 129.

In the following example, the command invocation


CTTHCMD /ASnconn1 CRTPGM PGM(MYLIB/ABC) ACTGRP(XYZ) MODULE(ABC DEF)
results in a program ABC being created in library MYLIB, from modules ABC and DEF
located in the current library. The program will run in a named activation group XYZ.

Chapter 8. Creating an OS/400 Program 133


Invoking the Binder to Create a Program

Note: If you also specify the /Q parameter, you do not see the generated informa-
tional messages.

Invoking CRTPGM From an AS/400 Command Line


To create a program object using the CRTPGM command from the AS/400:
1. Sign on to your AS/400
2. Type CRTPGM followed by the parameters you wish to specify

If you are not sure of the exact parameters to choose from, type CRTPGM, then press
the F4 Prompt key and enter the appropriate values for the command parameters as
prompted. Pressing the F1 Help key may provide further assistance.

How the Binder Resolves Imports


Once you have entered the CRTPGM command, the system performs the following
actions:
1. Copies listed modules into what will become the program object and links any
service programs to the program object.
2. Identifies the module containing the program entry procedure and locates the first
import in this module.
3. Checks the modules in the order in which they are listed and matches the first
import with a module export.
4. Returns to the first module and locates the next import.
5. Resolves all imports in the first module.
6. Continues to the next module and resolves all imports.
7. Resolves all imports in each subsequent module until all of the imports have been
resolved.
8. If any imports cannot be resolved with an export, terminates the binding process
without creating a program object.
9. Once all the imports have been resolved, completes the binding process and
creates the program object.

Handling Duplicate Variable Names


If you have specified in the binder language that a variable is to be exported (using
the EXPORT keyword), it is possible that the variable name will be identical to a vari-
able in another procedure within the bound program object.

Use the *DUPPROC option on the CRTPGM OPTION parameter to allow duplicate pro-
cedure names.

134 IBM VisualAge C++ for OS/400 C++ User’s Guide


Changing a Module or a Program Object

See ILE Concepts, for further information on how to handle this situation.

Using a Binder Listing


The binding process can optionally produce a binder listing that describes the
resources used, symbols and objects encountered, and problems that were resolved, or
not resolved, in the binding process.

The listing is produced as a spooled file for the job you use to enter the CRTPGM
command. You can choose a DETAIL parameter value to generate the listing at three
levels of detail:
Ÿ *BASIC
Ÿ *EXTENDED
Ÿ *FULL

The default is not to generate a listing. If it is generated, the binder listing includes
the sections described in Figure 13, depending on the value specified for DETAIL.
Figure 13. Sections of the Binder Listing based on the DETAIL Parameter

Section Name *BASIC *EXTENDED *FULL


Command Option Summary X X X
Brief Summary Table X X X
Extended Summary Table X X
Binder Information Listing X X
Cross-Reference Listing X
Binding Statistics X

The information in this listing can help you diagnose problems if the binding was not
successful, or give feedback about what the binder encountered during the binding
process.

Figure 14 on page 136 shows the basic binder listing for a program CVTHEXPGM.
Note that this listing is taken out of context. It only serves to illustrate the type of
information you may find in a binder listing.

See the ILE Concepts, for more information on binder listings.

Changing a Module or a Program Object


There are many reasons why you may want to change a module or a program object:
Ÿ An object may need to be changed to accommodate enhancements, or for mainte-
nance reasons.

Chapter 8. Creating an OS/400 Program 135


Changing a Module or a Program Object

Create Program Page 1


5763SS1 V3R6Mð 95ð9ð9 MYLIB/CVTHEXPGM AS4ððSð1 ð9/22/95
23:24:ðð
Program . . . . . . . . . . . . . . . . . . . . . : CVTHEXPGM
Library . . . . . . . . . . . . . . . . . . . . : MYLIB
Program entry procedure module . . . . . . . . . . : \FIRST
Library . . . . . . . . . . . . . . . . . . . . :
Activation group . . . . . . . . . . . . . . . . . : \NEW
Creation options . . . . . . . . . . . . . . . . . : \GEN \NODUPPROC \NODUPVAR \WARN \RSLVREF
Listing detail . . . . . . . . . . . . . . . . . . : \BASIC
Allow Update . . . . . . . . . . . . . . . . . . . : \YES
User profile . . . . . . . . . . . . . . . . . . . : \USER
Replace existing program . . . . . . . . . . . . . : \YES
Authority . . . . . . . . . . . . . . . . . . . . : \LIBCRTAUT
Target release . . . . . . . . . . . . . . . . . . : \CURRENT
Allow reinitialization . . . . . . . . . . . . . . : \NO
Text . . . . . . . . . . . . . . . . . . . . . . . : \ENTMODTXT
Module Library Module Library Module Library Module Library
CVTHEXPGM MYLIB
Service Service Service Service
Program Library Program Library Program Library Program Library
CVTTOHEX MYLIB
Binding Binding Binding Binding
Directory Library Directory Library Directory Library Directory Library
\NONE
Create Program Page 2
5763SS1 V3R6Mð 95ð9ð9 MYLIB/CVTHEXPGM AS4ððSð1 ð9/22/95
23:24:ðð
Brief Summary Table
Program entry procedures . . . . . . . . . . . : 1
Symbol Type Library Object Identifier
\MODULE MYLIB CVTHEXPGM _QRNP_PEP_CVTHEXPGM
Multiple strong definitions . . . . . . . . . : ð
Unresolved references . . . . . . . . . . . . : ð

\ \ \ \ \ E N D O F B R I E F S U M M A R Y T A B L E \ \ \ \ \
Create Program Page 3
5763SS1 V3R6Mð 95ð9ð9 MYLIB/CVTHEXPGM AS4ððSð1 ð9/22/95
23:24:ðð
Binding Statistics
Symbol collection CPU time . . . . . . . . . . . . . . . . . : .ð16
Symbol resolution CPU time . . . . . . . . . . . . . . . . . : .ðð4
Binding directory resolution CPU time . . . . . . . . . . . : .175
Binder language compilation CPU time . . . . . . . . . . . . : .ððð
Listing creation CPU time . . . . . . . . . . . . . . . . . : .ð68
Program/service program creation CPU time . . . . . . . . . : .234
Total CPU time . . . . . . . . . . . . . . . . . . . . . . . : .995
Total elapsed time . . . . . . . . . . . . . . . . . . . . . : 3.531
\ \ \ \ \ E N D O F B I N D I N G S T A T I S T I C S \ \ \ \ \
\CPC5Dð7 - Program CVTHEXPGM created in library MYLIB.
\ \ \ \ \ E N D O F C R E A T E P R O G R A M L I S T I N G \ \ \ \ \

Figure 14. Example of a Basic Binder Listing

You can isolate what needs to be changed by using debugging information or the
binder listing from the CRTPGM command. From this information you can
determine what modules, procedures, or fields need to change.
Ÿ You may want to change the optimization level or observability of a module or
program.

136 IBM VisualAge C++ for OS/400 C++ User’s Guide


Changing a Module or a Program Object

This is often the case when you want to debug a program or module, or when
you are ready to put a program into production. Such changes can be performed
more quickly and use fewer system resources than the re-creation of the object in
question.
Ÿ You may want to reduce the program size once you have completed an applica-
tion.
ILE program objects have additional data added to them, which makes them
larger than similar OPM or EPM program objects.

Each of the above approaches requires different data to make the change.

Updating a Program
In general, you can update a program by replacing modules as needed. You do not
have to re-create the program object. The ability to replace specific modules is
helpful if, for example, you are supplying an application to other sites that are already
using the program. You need only send the revised modules, and the receiving site
can update the application using the UPDPGM and UPDSRVPGM commands.

The update commands work with both program and module objects. The parameters
for these commands are very similar to those for the Create Program (CRTPGM)
command. For example, to replace a module in a program, you would enter the
module name for the MODULE parameter and the library name.

To use the UPDPGM command, the modules to be replaced must be located in the
same libraries they were in when the program was created.

You can specify that all modules, or only some subsets of modules, are to be
replaced.

See ILE Concepts, and the CL Reference for more information on the UPDPGM
command.

Changing the Optimization Level


Optimization is the process through which the system looks for processing shortcuts
that reduce the amount of system resources necessary to produce output. Processing
shortcuts are translated into machine code, allowing the procedures in a module to run
more efficiently. A highly optimized program or service program should run faster
than it would without optimization.

You control the level of optimization through the /O compiler options. Changing the
desired optimization level requires recompiling your source code. See “Code
Generation Options” on page 117 for details on the /O compiler options and opti-
mization levels.

Chapter 8. Creating an OS/400 Program 137


Changing a Module or a Program Object

You should be aware of the following limitations when working with optimized code:
Ÿ In general, the higher the optimizing request, the longer it takes to create an
object.
Ÿ At higher levels of optimization, the values of fields may not be accurate when
they are displayed in a debug session, or after the program recovers from an
exception.
Ÿ Optimized code may have altered breakpoints and step locations used by the
source debugger, since the optimization changes may rearrange or eliminate some
statements.
To circumvent this restriction while debugging, you can lower the optimization
level of a module to display fields accurately as you debug a program, and then
raise the level again afterwards, to improve the program efficiency as you get the
program ready for production.

Removing Observability
A module has observability when it contains data that allows it to be changed
without being compiled again. Two types of data can make a module observable:
Create Data This data is necessary to translate the code into machine instructions.
The object must have this data before you can change the optimiza-
tion level. It is represented by the *CRTDTA value on the RMVOBS
parameter of the Change Program (CHGPGM) command.
Debug Data This data enables an object to be debugged. It is represented by the
*DBGDTA value on the RMVOBS parameter of the CHGPGM command.

The addition of these types of data increases the size of the object. Consequently,
you may at some point want to remove the data in order to reduce object size.
However, once the data is removed, so is the object's observability. To regain it, you
must recompile the source and re-create the program.

To remove either kind of data from a program or module, use the CHGMOD or the
CHGPGM command. Again, once you have removed the data, it is not possible to
change the object in any way unless you re-create it. Therefore, ensure that you have
access to all source required to create the program, or that you have a comparable
program object with create data.

Reducing an Object's Size


The Create Data (*CRTDTA) value associated with an ILE program or module may
make up more than half of the object's size. By removing or compressing this data,
you reduce the secondary storage requirements for your programs significantly.

138 IBM VisualAge C++ for OS/400 C++ User’s Guide


Changing a Module or a Program Object

An alternative is to compress the object through using the Compress Object


(CPROBJ) command. A compressed object takes up less system storage than an
uncompressed one. When the compressed program is called, the part of the object
containing the executable code is automatically decompressed. You can also decom-
press an object by using the Decompress Object (DCPOBJ) command.

See the CL Reference for more information on the CPROBJ and DCPOBJ com-
mands.

Chapter 8. Creating an OS/400 Program 139


Changing a Module or a Program Object

140 IBM VisualAge C++ for OS/400 C++ User’s Guide


Overview of the Service-Program Concept

9 Creating a Service Program

Creating a service program involves compiling source code into module objects and
binding one or more module objects into a service program object.

Topics in this chapter cover:


Ÿ Overview of the service program concept
Ÿ Invoking the binder to create a service program

An example illustrates how to create a service program.

Overview of the Service-Program Concept


A service program is an OS/400 object of type \SRVPGM. Service programs are
typically used for common functions that are frequently called by other procedures
within an application and across applications. For example, the ILE compilers use
service programs to provide run-time services such as math functions and input/output
routines.

Service programs simplify maintenance, and reduce storage requirements, because


only a single copy of a service program is maintained and stored.

Differences between Programs and Service Programs


A service program differs from a program in two ways:
Ÿ A service program is bound to existing programs or other service programs. It
cannot run independently.
Ÿ A service program does not contain a program entry procedure. Therefore, you
cannot call a service program using an "OS" linkage specification. However, you
can call a service program with a "c" linkage specification, because it does
contain at least one user entry procedure.
See the VisualAge C++ for OS/400 C++ Programming Guide for information
on calling ILE procedures, and linkage specifications.

Binding a Service Program to a Program


Service programs are bound by reference. This means that the content of the service
program is not copied into the program to which it is bound. Instead, linkage infor-
mation about the service program is bound into the program.

 Copyright IBM Corp. 1995 141


Invoking the Binder to Create a Service Program

This process is different from the static binding process used to bind modules into
programs. However, you can still call the service program's exported procedures as if
they were statically bound. The initial activation is longer, but subsequent calls to
any of the service program's exported procedures are faster than program calls.

Invoking the Binder to Create a Service Program


Once an ILE module has been created, it can be used to create a service program
with the Create Service Program (CRTSRVPGM) command. You can also use
modules created with other ILE language compilers, such as ILE C/400, ILE
RPG/400, or ILE COBOL/400.

Parameters for the CRTSRVPGM Command


You can specify a number of parameters with the CRTSRVPGM command, as listed
in Figure 15. Each parameter has default values which are used whenever you don't
specify your own values.

See the CL Reference for a full description of the CRTSRVPGM command and
its parameters.

Figure 15. Parameters and Default Values for CRTSRVPGM Command

Parameter Group Parameter(Default Value)


Identification SRVPGM(library name/service program name)
MODULE(*SRVPGM)
Program access EXPORT(*SRCFILE)
SRCFILE(*LIBL/QSRVSRC)
SRCMBR(*SRVPGM)
Binding BNDSRVPGM(*NONE)
BNDDIR(*NONE)
Run time ACTGRP(*CALLER)
Miscellaneous OPTION(*GEN *NODUPPROC *NODUPVAR *WARN
*RSLVREF)
DETAIL(*NONE)
ALWUPD(*YES)
ALWRINZ(*NO)
REPLACE(*YES)
AUT(*LIBCRTAUT)
TEXT(*ENTMODTXT)
TGTRLS(*CURRENT)
USRPRF(*USER)

142 IBM VisualAge C++ for OS/400 C++ User’s Guide


Invoking the Binder to Create a Service Program

How to Issue the CRTSRVPGM Command


You issue the CRTSRVPGM command in the same way as you issue the CRTPGM
command:
Ÿ From the WorkFrame environment, invoke the BIND action and select
CRTSRVPGM.
Ÿ From an OS/2 command line use the option /B"crtsrvpgm
srvpgm(xxxx/yyyy)" on the iccas compiler invocation command
Ÿ From an OS/2 command line specify the CRTSRVPGM parameter on the
CTTHCMD command
Ÿ From an AS/400 command line issue the CRTSRVPGM command

Invoking CRTSRVPGM from the WorkFrame Environment


If you have already created a project that contains all the files for the application
you are working on, see “Creating Programs and Service Programs” on page 24 for
details on how to invoke the Bind action.

If you have not yet created a project for your application and need help, see
Part 1, “Developing OS/400 Applications with WorkFrame” on page 1 first.

Invoking CRTSRVPGM through the /B Compiler Option


When you invoke the compiler from the OS/2 command line through iccas, using
default compiler options, a program object (\PGM) is automatically created on the
AS/400 (if a host connection was established prior to the invocation).

To create a service program (\SRVPGM) instead, you must specify the /B compiler
option, and pass the CRTSRVPGM command and its parameters as a character string
following the option. For example:
iccas /ASlmylib /B"crtsrvpgm srvpgm(mylib/sp1)" myprog.cpp
is equivalent to specifying
CRTSRVPGM SRVPGM(MYLIB/SP1) MODULE(MYLIB/MYPROG)
on an AS/400 command line, and results in the creation of the service program SP1
on AS/400, from source file myproga.cpp, using default parameters on the
CRTSRVPGM command.

If the module already exists, you specify the module name instead of the source file,
when you invoke the compiler by specifying:
iccas /ASlmylib /B"crtsrvpgm srvpgm(mylib/sp1)" myprog
which is equivalent to specifying:
CRTSRVPGM SRVPGM(MYLIB/SP1) MODULE(MYLIB/MYPROG)

Chapter 9. Creating a Service Program 143


Invoking the Binder to Create a Service Program

on an AS/400 command line.

You can also create a service program from a source file and an existing module by
specifying:
iccas /B"crtsrvpgm srvpgm(service1)" myprog1.cpp myprog2
which is equivalent to specifying:
CRTSRVPGM SRVPGM(MYLIB/SERVICE1) MODULE(MYLIB/MYPROG1 MYLIB/MYPROG2)
on an AS/400 command line. This command results in the creation of the service
program SERVICE1 on AS/400, from source file myprog1.cpp, and module MYPROG2.

Invoking CRTSRVPGM through the CTTHCMD Command


The CTTHCMD lets you send a command to the AS/400 directly from your work-
station. If you want to use this interface to send the binding command, follow the
syntax:
CTTHCMD /ASnname hostcommand
or
CTTHCMD @filename
as explained in “Invoking CL Commands from OS/2 through CTTHCMD” on
page 129 .

In the following example, the command invocation


CTTHCMD /ASnconn1 CRTSRVPGM SRVPGM(MYLIB/SP1) MODULE(M1)
results in the service program SP1 being created in the library MYLIB from module M1
located in the current library.

Invoking CRTSRVPGM from the AS/400 Command Line


To create a service program using the CRTSRVPGM command from the AS/400:
1. Sign on to your AS/400.
2. Type CRTSRVPGM followed by the parameters you wish to specify.

If you are not sure of the exact parameters to choose from, type CRTSRVPGM, then
press the F4 Prompt key and enter the appropriate values for the command parameters
as prompted. Pressing the F1 Help key may provide further assistance.

Updating or Changing a Service Program


You can update or change a service program in the same way you modify a program
object. In other words, you can:
Ÿ Update the service program (using UPDSRVPGM)
Ÿ Change the optimization level (using CHGSRVPGM)
Ÿ Remove observability (using CHGSRVPGM)

144 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of How to Create a Service Program

Ÿ Reduce the size (using CPROBJ)

See “Changing a Module or a Program Object” on page 135 for more informa-
tion on any of the above points. p.If you use binder language, a service program can
be updated without requiring programs calling it to be recompiled. For example, to
add a new procedure to an existing service program:
1. Create a module object for the new procedure.
2. Modify the binder-language source file to handle the interface associated with the
new procedure. Add any new export statements following the existing ones.
See “Updating a Service Program Export List” on page 156 for details on
modifying binder-language source files.
3. Re-create the original service program and include the new module.

New programs can access the new functions. Since the old exports are in the same
order, they can still be used by the existing programs. Until it is necessary to also
update the existing programs, they do not have to be recompiled.

See ILE Concepts for more information on updating service programs.

Related CL commands
The following CL commands can be used with service programs:
Ÿ Create Service Program (CRTSRVPGM)
Ÿ Change Service Program (CHGSRVPGM)
Ÿ Display Service Program (DSPSRVPGM)
Ÿ Delete Service Program (DLTSRVPGM)
Ÿ Update Service Program (UPDSRVPGM)
Ÿ Work with Service Program (WRKSRVPGM)

Example of How to Create a Service Program


The following example shows how to create a service program SEARCH that can be
called by other programs to locate a character string in any given string of characters.

Program Files
The SEARCH program is implemented as a class object Search. The class Search
contains:
Ÿ Three private data members: skippat, needle_p, and needle_size
Ÿ Three constructors, each taking different arguments
Ÿ A destructor
Ÿ An overloaded function where(), that takes four different sets of arguments

The service program is composed of the following files:

Chapter 9. Creating a Service Program 145


Example of How to Create a Service Program

Ÿ A user-defined header file search.h


Ÿ A source code file search.cpp
Ÿ A source code file where.cpp

User Header File


The class and function declarations are placed into a separate header file, search.h,
shown below:

// header file search.h


// contains declarations for class Search, and inlined function
definitions

#include <iostream.h>

class Search {
private:
char skippat[256];
char \ needle_p;
int needle_size;

public:
// Constructors
Search( unsigned char \ needle, int size);
Search ( unsigned char \ needle);
Search ( char \ needle);

//Destructor
˜Search () { delete needle_p;}

//Overloaded member functions


unsigned int where ( char \ haystack) {
return where (haystack, strlen(haystack));
}
unsigned int where ( unsigned char \ haystack) {
return where (haystack, strlen((const char \)haystack));
}
unsigned int where ( char \ haystack, int size) {
return where ( (unsigned char \) haystack, size);
}
unsigned int where ( unsigned char \ haystack, int size);
} ;

Source Code Files


The definitions for the member functions of class Search that are not inlined in the
class declaration are contained in two separate files: the source file search.cpp,
which contains constructor definitions for class Search; and where.cpp, which con-
tains the member function definition. These files are shown below:

146 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of How to Create a Service Program

// header file search.h


// contains the definitions for the constructors for class Search

#include "search.h"

Search::Search( unsigned char \ needle, int size)


: needle_size(size) , needle_p ( new char [size])
{

memset (skippat, needle_size, 256);


for (unsigned int i=ð; i<size; ++i) {
skippat [needle [i]] = size -i-1;
}
memcpy (needle_p, needle, needle_size);
}

Search::Search ( unsigned char \ needle) {


needle_size = strlen( (const char \)needle) ;
needle_p = new char [needle_size];

memset (skippat, needle_size, 256);


for (unsigned int i=ð; i<needle_size; ++i) {
skippat [needle [i]] = needle_size -i-1;
}
memcpy(needle_p, needle, needle_size);
}

Search::Search ( char \ needle) {


needle_size = strlen( needle) ;
needle_p = new char [needle_size];

memset (skippat,needle_size, 256);


for (unsigned int i=ð; i<needle_size; ++i) {
skippat [needle [i]] = needle_size -i-1;
}
memcpy(needle_p, needle, needle_size);
}

// where.cpp
// contains definition of overloaded member function for class Search

#include "search.h"

unsigned int Search::where ( unsigned char \ haystack, int size)


{ unsigned int i, t;
int j;
for ( i= needle_size-1, j = needle_size-1; j >= ð; --i, --j ){
while ( haystack[i] != needle_p[j]) {
t = skippat [ haystack [i]] ;
i += (needle_size - j > t) ? needle_size - j : t ;

Chapter 9. Creating a Service Program 147


Example of How to Create a Service Program

if (i >= size)
return size;
j = needle_size - 1;
}
}
return ++i;
}

The modules that result from the compilation of these source files, SEARCH and
WHERE, will be bound into a service program, SERVICE1.

Creating the Service Program


Establish a connection between your workstation and an AS/400 system, and decide
how you want to invoke the compiler and binder.

For example, on the OS/2 command line, enter:


iccas /ASlmylib /B"crtsrvpgm srvpgm(mylib/service1) export(\all)" search
to create service program SERVICE1 from the C++ source files search.cpp and
where.cpp.

By default, iccas places the service program into your current library on the AS/400.
The compiler option ASlname changes this target library to MYLIB.

The parameter export(*all) specifies that all data and procedures exported from the
modules are also exported from the service
program.

Binding the Service Program to a Program


A very short application consisting of a program MYPROG is bound to the service
program to complete this example. The source code for MYPROG, myprog.cpp, is
shown below.
Note: This sample application has been reduced to minimum functionality, its main
purpose being to demonstrate how to create a service program.

// myprog.cpp
// Finds a character string in another character string.

#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include "search.h"

#define HS "Find the needle in this haystack"

void main () {

148 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of How to Create a Service Program

int i;
Search token("needle");
i = token.where (HS, sizeof(HS));
cout << "The string was found in position " << i << endl;
}

The program creates an object of class search. It invokes the constructor with a
value that represents the string of characters ("needle") to be searched for. It calls the
member function where() with the string to be searched ("Find the needle in this
haystack"). The string "needle" is located, and its position in the target string "Find a
needle in this haystack" is returned and printed.

To create the program MYPROG in library MYLIB, and bind it to the service program
SERVICE1, enter the following on the OS/2 command line:
iccas /B"crtpgm pgm(mylib/myprog) bndsrvpgm(mylib/service1)" myprog.cpp

Figure 16 shows the internal and external function calls between program MYPROG
and service program SERVICE1.

PGM MYPROGA
main function
Internal function call

search constructor

Function call between


PGM and SRVPGM

SRVPGM SERVICE1

where() function

Figure 16. Calls between Program and Service Program

When MYPROG is created, it includes information regarding the interface it uses to


interact with the service program.

To run the program from an OS/2 command line type:


CTTHCMD call mylib/myprog

During the process of making MYPROG ready to run, the system verifies that:

Chapter 9. Creating a Service Program 149


Example of How to Create a Service Program

Ÿ The service program SERVICE1 in library MYLIB can be found.


Ÿ The public interface used by MYPROG when it was created is still valid at run
time.

If either of the above is not true, an error message is issued.

The output of MYPROG is:


The string was found in position 9
Note: The output of this call is placed in a spool file QPRINT on the AS/400. It is
not visible from the OS/2 workstation.

150 IBM VisualAge C++ for OS/400 C++ User’s Guide


Determining Exports from Service Programs

10 Working With Exports From Service Programs

A service program contains procedures and data items that can be exported to satisfy
import requests by programs that call this service program.

The previous chapter discussed how to bind module objects into programs. Topics in
this chapter cover:
Ÿ Determining exports from service programs
Ÿ Creating a binder-language source file
Ÿ Handling unresolved import requests during program creation

Examples illustrate the following concepts:


Ÿ Creating a service program using Binder Language
Ÿ Creating a program with circular references
Ÿ Binding a program to a non-existing service program
Ÿ Updating a service program export list

Determining Exports from Service Programs


A service program exports procedures and data items that can be imported by other
programs. These exports represent the interface to the service program. In the C++
programming language, procedures and data items correspond to functions and vari-
ables.

You can use information about exports that are available from the modules that form
a particular service program to create a binder-language source file that defines the
interface to this service program. A binder-language source file specifies the
exports the service program makes available to all programs that call it. This file can
be specified on the EXPORT parameter of the CRTSRVPGM command.

Binder language gives you better control over the exports of a service program. This
control can be very useful if you want to:
Ÿ Determine export and import mismatches in an application
Ÿ Add functionality to service programs
Ÿ Reduce the impact of changes to a service program on the users of an application
Ÿ Mask certain service-program exports from service-program users
That is, by not listing certain functions or variables in the binder-language source
file, you can prevent any calling programs from having access to these exports

 Copyright IBM Corp. 1995 151


Determining Exports from Service Programs

When creating a service program, you should consider:


Ÿ Whether or not you intend to update the program at a later date
Ÿ Whether or not any updates involve changes to its interface

If the interface to a service program changes, you may have to rebind all programs
bound to the original service program. However, depending on the changes and how
you implement them, you may be able to reduce the amount of rebinding if you
create the service program using binder language. In this case, after updating the
binder language source to identify new exports, you need to rebind only those pro-
grams that require the new exports.

Displaying Export Symbols With the Display Module Command


To find out which exports are available from a module, type:
DSPMOD library-name/module-name
on an AS/400 command line, indicating the module name and the library where the
module is stored. This command brings up the Display Module Information
display. At the bottom of this display, you find information about exported defined
symbols, consisting of the name and type of each symbol that can be exported from
the module.
Note: When the compiler compiles a C++ source file, it encodes all C++ symbolic
names to include type and scoping information. This encoding process is called name
mangling. The symbol names in the sample display below are shown in mangled
form.

à@ ð
Display Module Information Display 3 of 3
Module . . . . . . . . . . . . : SEARCH
Library . . . . . . . . . . : MYLIB
Detail . . . . . . . . . . . . : \EXPORT
Module attribute . . . . . . . :

Exported defined symbols:

Symbol Name Symbol Type


__ct__6SearchFPc PROCEDURE
__ct__6SearchFPUc PROCEDURE
__ct__6SearchFPUci PROCEDURE

á ñ

Figure 17. Display Module Information Screen for a Sample Module SEARCH

The source code for module SEARCH is shown in “Source Code Files” on
page 146

152 IBM VisualAge C++ for OS/400 C++ User’s Guide


Creating a Binder-Language Source File

Creating a Binder-Language Source File


Binder language is based on the exports available from modules that are bound into
service programs. A binder-language source file must contain the following entries:
1. The Start Program Export (STRPGMEXP) command identifies the beginning of
the list of exports from the service program
2. Export Symbol (EXPORT) commands identify each a symbol name available to
be exported from the service program
3. The End Program Export (ENDPGMEXP) command identifies the end of the list
of exports from the service program

The following example shows the structure of a binder-language source file:

STRPGEXP PGMLEVEL(\CURRENT)
EXPORT SYMBOL("mangled_procedure_name_a")
EXPORT SYMBOL("mangled_procedure_name_b")
...
...
EXPORT SYMBOL("mangled_procedure_name_x")
ENDPGMEXP
Note: You must specify the mangled name of each symbol on the EXPORT
command, because the binder looks for the mangled names of exports when it tries to
resolve import requests from other modules.

Once all the modules to be bound into a service program have been created, you can
create the binder-language source file. You can write this file yourself, using the
Source Entry Utility (SEU), or you can let the AS/400 system generate it for you,
through the Retrieve Binder Source (RTVBNDSRC) command.

Creating Binder Language Using SEU


You can use the Source Entry Utility (SEU) to create a binder-language source file:
1. Create a source physical file QSRVSRC on the AS/400 in library MYLIB
2. Create a member MEMBER1 that will contain the binder language.
3. Use the DSPMOD command to display the symbols that can be exported from
each module
4. Decide which exports you want to make available to calling programs
5. Use the Source Entry Utility (SEU) to enter the syntax of the binder language

You need one export statement for each procedure whose exports you want to make
available to the caller of the service program. Do not list symbols that you do not
want to make available to calling programs.

Chapter 10. Working With Exports From Service Programs 153


Creating a Binder-Language Source File

For example, based on the information shown in Figure 17 on page 152, the binder-
language source file for module SEARCH could list the following export symbols:

STRPGEXP PGMLEVEL(\CURRENT)
EXPORT SYMBOL(" __ct__6SearchFPc")
EXPORT SYMBOL(" __ct__6SearchFPUc")
EXPORT SYMBOL(" __ct__6SearchFPUci")
ENDPGMEXP

Creating Binder Language Using the RTVBNDSRC Command


The Retrieve Binder Source (RTVBNDSRC) command can automatically create a
binder-language source file. It retrieves the exports from a module, or a set of
modules. It generates the binder language for these exports, and places exports and
binder language in a specified file member. This file member can later be used as
input to the EXPORT parameter of the CRTSRVPGM command.
Note: After the binder language has been retrieved into a source file member, you
can edit the binder language and modify it as needed, for example, if you make
changes to a module, or if you want to make certain exports unavailable to calling
programs.

The syntax for the RTVBNDSRC command is:

55──RTVBNDSRC──┬───────────┬──Module──┬───────────┬─────────────5
└─Library1/─┘ └─Library2/─┘
5──┬────────────────────┬──┬──────────────────────┬─────────────5
└─Export source file─┘ └─Export source member─┘
5──┬──────────┬────────────────────────────────────────────────5%
├─\ADD─────┤
└─\REPLACE─┘

The RTVBNDSRC command takes the following parameters:


Library1
Qualifies the name of a module.
Module
Specifies the name(s) of the module(s) from which to retrieve the exported
symbols.
Library2
Qualifies the name of the export source file.

154 IBM VisualAge C++ for OS/400 C++ User’s Guide


Creating a Binder-Language Source File

Export source file


Specifies the name of the source file that is to hold the export source member. If
the source file does not exist, it is created.
Export source member
Specifies the name of the export source member that is to hold the binder lan-
guage for the exported symbols. If the member does not exist, it is created.
Add or replace statements
Specifies whether the generated binder language statements are added to existing
statements or replace them.

For detailed information on the RTVBNDSRC command and its parameters enter
RTVBNDSRC on an AS/400 command line and press F1 for Help.

Example of Creating Binder Language With RTVBNDSRC


The following example shows how to create a binder-language source file for module
SEARCH, located in library MYLIB, using the RTVBNDSRC command. The source
code for module SEARCH is shown in “Source Code Files” on page 146. On the OS/2
command line type:

CTTHCMD RTVBNDSRC MODULE(MYLIB/SEARCH) SRCFILE(MYLIB/QSRVSRC) SRCMBR(ONE)

This command automatically:


1. Creates a source physical file QSRVSRC on the AS/400 in library MYLIB
2. Adds a member ONE to QSRVSRC
3. Generates binder language from module SEARCH in library MYLIB and places it in
member ONE

Member ONE in file MYLIB/QSRVSRC now contains the following binder language:

Chapter 10. Working With Exports From Service Programs 155


Updating a Service Program Export List

à@ ð
Columns . . . : 1 71 Browse MYLIB/QSRVSRC
SEU==> ONE
FMT \\ ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
\\\\\\\\\\\\\\\ Beginning of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ðððð.ð1 STRPGMEXP PGMLVL(\CURRENT)
ðððð.ð2 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð3 /\ \MODULE SEARCH MYLIB 95/ð6/1ð 17:34:41 \/
ðððð.ð4 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð5 EXPORT SYMBOL("__ct__6SearchFPc")
ðððð.ð6 EXPORT SYMBOL("__ct__6SearchFPUc")
ðððð.ð7 EXPORT SYMBOL("__ct__6SearchFPUci")
ðððð.ð8 ENDPGMEXP
\\\\\\\\\\\\\\\\\\ End of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

á ñ

Figure 18. Binder-Language Source File Generated for Module SEARCH

Updating a Service Program Export List


You can use binder language to reflect changes in the list of exports a service
program makes available. When you create binder language, a signature is generated
from the order in which the modules that form a service program are processed, and
from the order in which symbols are exported from these modules. The EXPORT
keyword in the binder language identifies the procedure and data item names that
make up the signature for the service program.

When you make changes to the exports of a service program this does not necessarily
mean that all programs that call this service program must be re-created. You can
implement changes in the binder language such that they are backward compatible.
Backward-compatible means that programs which depend on exports that remain
unchanged do not need to be re-created.

To ensure backward compatibility, add new procedure or data item names to the end
of the export list, and recreate the service program with the same signature. This lets
existing programs still use the service program, because the order of the unchanged
exports remains the same.
Note: When changes to a service program result in a loss of exports, or in a change
of existing exports, it becomes difficult to update the export list without affecting
existing programs that require its services. Changes in the order, number, or name of
exports result in a new signature that requires the re-creation of all programs and
service programs that use the changed service program.

See ILE Concepts for a discussion of the signature of a service program.

156 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Demangling Functions
You can retrieve the mangled names of exported symbols with the RTVBNDSRC
command. To help you find the corresponding demangled names, the runtime library
contains a small class hierarchy of functions that you can use to demangle names and
examine the resulting parts of the name.

These demangling functions are available in both the static (.LIB) and dynamic
(.DLL) versions of the library. The interface is documented in the <demangle.h>
header file.

Using the demangling functions, you can write programs to convert a mangled name
to a demangled name and to determine characteristics of that name, such as its type
qualifiers or scope. For example, given the mangled name of a function, the program
returns the demangled name of the function and the names of its qualifiers. If the
mangled name refers to a class member, you can determine if it is static, const, or
volatile. You can also get the whole text of the mangled name.

To demangle a name, which is represented as a character array, create a dynamic


instance of the Name class and provide the character string to the class's constructor.
For example, to demangle the name f__1XFi, create:
char \rest;
Name \name = Demangle("f__1XFi", rest);

The demangling functions classify names into five categories: function names,
member function names, special names, class names, and member variable names.
After you construct an instance of class Name, you can use the Kind member function
of Name to determine what kind of Name the instance is. Based on the kind of name
returned, you can ask for the text of the different parts of the name or of the entire
name.

For the mangled name f__1XFi, you can determine:

name->Kind() == MemberFunction
((MemberFunctionName \) name)->Scope()->Text() is "X"
((MemberFunctionName \) name)->RootName() is "f"
((MemberFunctionName \) name)->Text() is "X::f(int)"

Chapter 10. Working With Exports From Service Programs 157


Example of Creating a Service Program Using Binder Language

If the character string passed to the Name constructor is not a mangled name, the
Demangle function returns NULL.

For further details about the demangling functions, refer to the information contained
in the <demangle.h> header file. If you installed VisualAge C++ for OS/400 using
default settings, this header file should be located in the INCLUDE directory under
the main VisualAge C++ for OS/400 installation directory.

Handling Unresolved Import Requests During Program Creation


An unresolved import is an import whose type and name do not yet match the type
and name of an export. Unresolved import requests do not necessarily prevent you
from creating a program or a service program. You can proceed in two ways:
Ÿ Specify the *UNRSLVREF option on the CRTPGM or CRTSRVPGM commands to
tell the binder to go ahead and create a program or service program, even if there
are imports in the modules, and no matching exports can be found.
Ÿ Change the order of program creation to avoid unresolved references.

Both approaches are demonstrated in “Example of Creating a Program with Cir-


cular References” on page 159.

Use the *UNRSLVREF option to convert, create, or build pieces of code when all the
pieces of code are not yet available. After the development or conversion phase has
finished and all import requests can be resolved, make sure you re-create the program
or service program that has the unresolved imports.

If you use the *UNRSLVREF option, specify DETAIL(*EXTENDED) or DETAIL(*FULL),


or keep the job log when the object is created, to identify the procedure or data item
names that are not found.
Note: If you have specified *UNRSLVREF and a program is created with unresolved
import requests, you receive an error message (MCH3203) when you try to run the
program.

Example of Creating a Service Program Using Binder Language


To create the service program described in the previous chapter using binder lan-
guage, follow these steps:
1. To create modules from all source files enter the following compiler invocation
on an OS/2 command line:

iccas /C search.cpp where.cpp

158 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Creating a Program with Circular References

The /C compiler option allows you to stop the compilation process after the
creation of the modules SEARCH and WHERE. The binder will not be invoked.
2. To create the corresponding binder-language source file, enter the following
command on the OS/2 command line:
CTTHCMD rtvbndsrc module(mylib/search mylib/where)
srcfile(mylib/qsrvsrc) srcmbr(two)
This command creates the binder-language source file shown in Figure 19.
3. To create service program SERVICE2 invoke the binder as follows:
iccas /B"crtsrvpgm srvpgm(mylib/service2) srcfile(mylib/qsrvsrc)
srcmbr(two)" search where

à@ ð
Columns . . . : 1 71 Browse MYLIB/QSRVSRC
SEU==> TWO
FMT \\ ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
\\\\\\\\\\\\\\\ Beginning of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ðððð.ð1 STRPGMEXP PGMLVL(\CURRENT)
ðððð.ð2 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð3 /\ \MODULE SEARCH MYLIB 95/ð6/11 15:3ð:51\/
ðððð.ð4 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð5 EXPORT SYMBOL("__ct__6SearchFPc")
ðððð.ð6 EXPORT SYMBOL("__ct__6SearchFPUc")
ðððð.ð7 EXPORT SYMBOL("__ct__6SearchFPUci")
ðððð.ð8 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð9 /\ \MODULE WHERE MYLIB 95/ð6/11 15:3ð:51\/
ðððð.1ð /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.11 EXPORT SYMBOL("where__6SearchFPUci")
ðððð.12 ENDPGMEXP
\\\\\\\\\\\\\\\\\\ End of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

á ñ

Figure 19. Binder-Language Source File Generated by the RTVBNDSRC Command

Example of Creating a Program with Circular References


A circular reference is a special case of unresolved import requests. It occurs, for
example, when a service program SP1 depends on imports from a service program
SP2, which in turn depends on an import from service program SP1. Figure 20 on
page 160 illustrates the unresolved import requests between program A and two
service programs, SP1 and SP2.

Chapter 10. Working With Exports From Service Programs 159


Example of Creating a Program with Circular References

PGM A

main()

SRVPGM SP1

func1()

SRVPGM SP2

func2()

Figure 20. Unresolved Import Requests in a Program With Circular References

Program Description
The following import requests occur between program A and the two service pro-
grams, SP1 and SP2, that are called by A:
1. Program A uses function func1(), which it imports from service program SP1.
2. Service program SP1 needs to import function func2() provided by service
program SP2, in order to provide func1() to program A.
3. Service program SP2, in turn, first needs to import func1 from service program
SP1 before being able to provide func2.

Program Files
The application consists of three source files, m1.cpp, m2.cpp, and m3.cpp, shown
below:

// m1.cpp

#include <iostream.h>
int main(void)
{
void func1(int);
int n = ð;

func1(n); // Function func1() is called.


}

160 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Creating a Program with Circular References

// m2.cpp

#include <iostream.h>
void func2 (int);
void func1(int x)
{
if (x<5)
{
x += 1;
cout << "This is from func1(), n=" << x << endl;
func2(x); // Function func2() is called.
}
}

// m3.cpp

#include <iostream.h>
void func1(int);
void func2(int y)
{
if (y<5)
{
y += 1;
cout << "This is from func2(), n=" << y << endl;
func1(y); // Function func1() is called.
}
}

Module Creation
Compile the source files m2.cpp and m3.cpp into module objects from which you
later create the service programs SP1 and SP2.. This allows you to display their
exports with the DSPMOD command, or to generate binder-language source with the
RTVBNDSRC command. To create module objects from the source files described
above, invoke the compiler from the OS/2 command line with the command:
iccas /C /ASlmylib m2.cpp m3.cpp

The /C compiler option indicates to the compiler that you do not want to create a
program object from the source files. The /ASlmylib option instructs the compiler to
create the module objects M2, and M3 in library MYLIB on the AS/400.

Binder-Language Creation
To generate binder language for module M2, from which you want to create service
program SP1, issue the following command on an OS/2 command line:

Chapter 10. Working With Exports From Service Programs 161


Example of Creating a Program with Circular References

CTTHMD rtvbndsrc module(mylib/m2) srcfile(mylib/qsrvsrc) srcmbr(bndlang1)

This command results in the following binder language being created for module M2,
in library MYLIB, source file QSRVSRC, file member BNDLANG1:

à@ ð
Columns . . . : 1 71 Browse MYLIB/QSRVSRC
SEU==> BNDLANG1
FMT \\ ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
\\\\\\\\\\\\\\\ Beginning of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ðððð.ð1 STRPGMEXP PGMLVL(\CURRENT)
ðððð.ð2 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð3 /\ \MODULE M2 MYLIB 95/ð6/11 18:ð7:ð4\/
ðððð.ð4 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð5 EXPORT SYMBOL("func1__Fi")
ðððð.ð6 ENDPGMEXP
\\\\\\\\\\\\\\\\\\ End of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

á ñ

Figure 21. Binder Language for Service Program SP1

To generate binder language for module M3, from which you want to create service
programs SP2, issue the following command on an OS/2 command line:
CTTHMD rtvbndsrc module(mylib/m3) srcfile(mylib/qsrvsrc) srcmbr(bndlang2)

This command results in the following binder language being created for module M3,
in library MYLIB, source file QSRVSRC, file member BNDLANG2:

à@ ð
Columns . . . : 1 71 Browse MYLIB/QSRVSRC
SEU==> BNDLANG2
FMT \\ ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
\\\\\\\\\\\\\\\ Beginning of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ðððð.ð1 STRPGMEXP PGMLVL(\CURRENT)
ðððð.ð2 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð3 /\ \MODULE M3 MYLIB 95/ð6/11 18:ð8:14 \/
ðððð.ð4 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð5 EXPORT SYMBOL("func2__Fi")
ðððð.ð6 ENDPGMEXP
\\\\\\\\\\\\\\\\\\ End of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

á ñ

Figure 22. Binder Language for Service Program SP2

Program Creation
Program A will be created from m1.cpp. Service program SP1 will be created from
M2. Service program SP2 will be created from M3.

162 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Creating a Program with Circular References

If you try and create service program SP1 from module M2, using the binder language
shown in Figure 21 and the compiler invocation:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP1)
SRCFILE(MYLIB/QSRVSRC) SRCMBR(BNDLANG1)" m2
you find that the binder tries to resolve the import for function func2(), but fails,
because it is not able to find a matching export. Therefore, service program SP1 is
not created.

If SP1 is not created, this leads to problems if you try and create service program SP2
from module M3 using the binder language shown in Figure 22 on page 162 and the
compiler invocation:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP2)
SRCFILE(MYLIB/QSRVSRC) SRCMBR(BNDLANG2)" m3

Service program SP2 is not created, because the binder fails in searching for the
import for func1() in service program S1P, which has not been created in the pre-
vious step.

If you try and create program A with the compiler invocation:


iccas/B"crtpgm pgm (A) bndsrvpgm(MYLIB/SP1 MYLIB/SP2) m1.cpp
the binder fails, since service programs SP1 and SP2 do not exist.

Handling Unresolved Import Requests with *UNRSLVREF


The following scenario shows how to use the parameter *UNRSLVREF to handle the
unresolved import requests which would otherwise prevent you from creating program
A.
1. To create service program SP1 from m2.cpp, type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP1) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG1) OPTION(\UNRSLVREF)" m2.cpp
Since the *UNRSLVREF option is specified, service program SP1 is created even
though the import request for func2() is not resolved.
2. To create service program SP2 from module M3, type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP2) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG2) OPTION(\UNRSLVREF)" m3.cpp
Since service program SP1 now exists, the binder resolves all the import requests
required, and service program SP2 is created successfully.
3. To re-create the service program SP1, type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP1) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG1) BNDSRVPGM(MYLIB/SP2)" m2

Chapter 10. Working With Exports From Service Programs 163


Example of Creating a Program with Circular References

Although service program SP1 does exist, the import request for func2() is not
resolved. Therefore, the re-creation of service program SP1 is required. Since
service program SP2 now exists, the binder resolves all import requests required
and, service program SP1 is created successfully.
4. To create program A, type:
iccas/B"CRTPGM PGM(MYLIB/A) BNDSRVPGM(MYLIB/SP1 MYLIB/SP2)" m1.cpp
Since service programs SP1 and SP2 do exist, the binder creates the program A.

Handling Unresolved Import Requests by Changing Program-Creation Order


You can also change the order of program creation to avoid unresolved references, by
first creating a service program with all modules, and then re-creating this same
service program later.
1. To generate binder language for modules M2 and M3, from which you want to
create service program SP1, issue the following command on an OS/2 command
line:
CTTHMD rtvbndsrc module(mylib/m2 mylib/m3) srcfile(mylib/qsrvsrc) srcmbr(
This command results in the binder language shown inFigure 23 on page 165
being created in library MYLIB, source file QSRVSRC, file member BNDLANG3.
2. To create service program SP1 from module M2 and module M3 type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP1) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG3)" m2.cpp m3.cpp
Since modules M2 and M3 are specified, all import requests are resolved, and
service program SP1 is created successfully.
3. To create service program SP2, type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP2) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG2) BNDSRVPGM(MYLIB/SP1)" m3.cpp
Since service program SP1 exists, the binder resolves all the import requests
required and service program SP2 is created successfully.
4. To re-create service program SP1, type:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/SP1) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDLANG1) BNDSRVPGM(MYLIB/SP2)" m2.cpp
Although service program SP1 does exist, the import request for func2() is not
resolved to the one in service program SP2. Therefore, a re-creation of service
program SP1 is necessary to make the circular reference work.
Since service program SP2 now exists, the binder can resolve the import request
for func2() from service program SP2, and service program SP1 is successfully
created.

164 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Binding a Program to a Nonexisting Service Program

5. To create program A, type:


iccas /B"CRTPGM PGM(MYLIB/A) BNDSRVPGM(MYLIB/SP1 MYLIB/SP2)" m1.cpp
Since service programs SP1 and SP2 do exist, the binder creates program A.

à@ ð
Columns . . . : 1 71 Browse MYLIB/QSRVSRC
SEU==> BNDLANG3
FMT \\ ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
\\\\\\\\\\\\\\\ Beginning of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
ðððð.ð1 STRPGMEXP PGMLVL(\CURRENT)
ðððð.ð2 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð3 /\ \MODULE M2 MYLIB 95/ð6/11 18:5ð:23 \/
ðððð.ð4 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð5 EXPORT SYMBOL("func1__Fi")
ðððð.ð6 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð7 /\ \MODULE M3 MYLIB 95/ð6/11 18:5ð:23 \/
ðððð.ð8 /\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\/
ðððð.ð9 EXPORT SYMBOL("func2__Fi")
ðððð.1ð ENDPGMEXP
\\\\\\\\\\\\\\\\\\ End of data \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

á ñ

Figure 23. Binder Language for Service Program SP1

Example of Binding a Program to a Non-existing Service Program


To successfully create a program or a service program, all required modules must
exist prior to invoking the binder.

However, if you want to bind a program to a non-existing service program, you can
create a "place-holder" service program first. Consider the following example:

A program MYPROG requires a function myprint() to be exported by a service


program PRINT. The code for the program is available in myprog.cpp. However, the
source for the service program does not yet exist. To work around this problem:
1. Create a source file dummy.cpp, such as:

//dummy.cpp
#include <iostream.h>

void function(void) {
cout << "I am a placeholder only" << endl;
return;
}
2. Compile and bind dummy.cpp into a service program PRINT:
iccas /B"crtsrvpgm srvpgm(mylib/print)" dummy.cpp

Chapter 10. Working With Exports From Service Programs 165


Example of Updating a Service-Program Export List

3. Create the source file for program MYPROG:

// myprog.cpp
#include <iostream.h>
#define size 8ð
void print(char \);

main() {
char text[size];
cout << "Enter text" << endl;
cin >> text;
print(text);
return;
}
4. Create the program MYPROG from myprog.cpp and bind it to the service program
PRINT:
iccas /B"crtpgm pgm(mylib/myprog) bndsrvpgm(mylib/print)
option(\unrslvref)" myprog.cpp
The option *UNRSLVREF ensures that the program will bind to the service
program, although there is no matching export for MYPROG's import void
print(char \).

Before you can run program MYPROG successfully, you must re-create service program
PRINT from the real source code, instead of from the place-holder code in dummy.cpp.
Note: MYPROG will only run successfully if PRINT actually exports a function that
matches MYPROG's import request.

Example of Updating a Service-Program Export List


The following example shows how to add a new procedure called cost2() to service
program COST without having to re-create the existing program COSTDPT1 that
requires an export from COST.

Program Description
The figure below shows the exports in the existing version of service program COST,
and in the updated version.

166 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Updating a Service-Program Export List

COST (OLD) COST (NEW)


┌───────────────┐ ┌────────────────┬
│ \SRVPGM │ │ \SRVPGM │
│ │ │ │
│ │ │ │
│ Exports: │ │ Exports: │
│ │ │ │
│ cost1() │ │ cost1() │
│ │ │ │
│ │ │ cost2() │
└───────────────┘ └────────────────┴

Figure 24. Exports from Service Program COST

The figure below shows the import requests in the existing program COSTDPT1, and in
the new program COSTDPT2.

COSTDPT1 (OLD) COSTDPT2 (NEW)


┌───────────────┐ ┌────────────────┐
│ \PGM │ │ \PGM │
│ │ │ │
│ Imports: │ │ Imports: │
│ │ │ │
│ cost1() │ │ cost2() │
│ │ │ │
│ │ │ │
└───────────────┘ └────────────────┘

Figure 25. Import requests in Programs COSTDPT1 and COSTDPT2

The binder language for the old version of service program COST is located in
member BND of source file QSRVSRC, in library MYLIB:

STRPGMEXP PGMLVL(\CURRENT)
EXPORT SYMBOL("cost1__Fi9_DecimalTXSP1ðSP2_")
ENDPGMEXP

The export signature is 94898385315FD06BB65E44D38A852904.

The updated binder language includes the new export procedure cost2(). It is
located in member BNDUPD of source file QSRVSRC, in library MYLIB:

STRPGMEXP PGMLVL(\CURRENT)
EXPORT SYMBOL("cost1__Fi9_DecimalTXSP1ðSP2_")
EXPORT SYMBOL("cost2__Fi9_DecimalTXSP1ðSP2_9_DecimalTXSP3SP1_")
ENDPGMEXP

Chapter 10. Working With Exports From Service Programs 167


Example of Updating a Service-Program Export List

The new export signature is 61E595C21D3EC9FDFD29749FB36B42D0.

In the binder language source that defines the old service program, the PGMLVL value
is changed from *CURRENT to *PRV:

STRPGMEXP PGMLVL(\PRV)
EXPORT SYMBOL("cost1__Fi9_DecimalTXSP1ðSP2_")
ENDPGMEXP

Its export signature is unchanged.


Note: If you want to ensure that existing programs can call the new version of the
service program without being re-created, make sure to:
1. Add the new exports to the end of the symbol list in the binder language
2. Explicitly specify a signature for the new version of the service program that is
identical to the signature of the old version.
See ILE Concepts for detailed information on how to specify an explicit sig-
nature for a service program.

Program Files
The source code for service program COST, module COST2, and programs COSTDPT1
and COSTDPT2 is shown below:

// cost1.cpp
// contains the export function cost1() for the old service program

#include <iostream.h>
#include <bcd.h>

_DecimalT<1ð,2> cost1 (
int q, // The quantity.
_DecimalT<1ð,2> p ) // The price.
{
_DecimalT<1ð,2> c; // The cost.

c = q\p;
return c;
}
// cost2.cpp
// contains the export function cost2() for the new service program

#include <iostream.h>
#include <bcd.h>

_DecimalT<1ð,2> cost2 (int quantity, _DecimalT<1ð,2> price,


_DecimalT<3,1> discount )

168 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of Updating a Service-Program Export List

{
_DecimalT<1ð,2> c = __D(quantity\price\discount/1ðð);
return c;
}

// costdpt1.cpp
// This program prompts users (from dept1) to enter the
// quantity, and price for a product. It uses function
// cost1() to calculate the cost, and prints the result out.

#include <iostream.h>
#include <bcd.h>
_DecimalT<1ð,2> cost1(int, _DecimalT<1ð,2>);

int main(void)
{
int quantity;
_DecimalT<1ð,2> cost;
_DecimalT<1ð,2> price;

cout << "Enter the quantity, please." << endl;


cin >> quantity;
cout << "Enter the price, please." << endl;
cin >> price;

cost = cost1(quantity, price);


cout << "The cost is $" << cost << endl;
}

// costdpt2.cpp
// This program prompts users (from dept2) to enter the
// quantity, price, and discount rate for a product.
// It uses function cost2() to calculate the cost, and prints
// the result out.

#include <iostream.h>
#include <decimal.h>
_DecimalT<1ð,2> cost2(int, _DecimalT<1ð,2>, _DecimalT<3,1>);

int main(void)
{
int quantity;
_DecimalT<1ð,2> price;
_DecimalT<1ð,2> cost;
_DecimalT<3,1> discount;

cout << "Enter the quantity, please." << endl;


cin >> quantity;
cout << "Enter the price, please." << endl;
cin >> price;
cout << "Enter the discount, please.( %)" << endl;
cin >> discount;

Chapter 10. Working With Exports From Service Programs 169


Example of Updating a Service-Program Export List

cost = cost2(quantity, price, discount);


cout << "The cost is be $" << cost << endl;
}

Program Creation
1. Create service program COST from source file cost1.cpp, using the binder
source member BND, located in source file QSRVSRC, in library MYLIB:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/COST) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BND) DETAIL(\EXTENDED)" cost1.cpp
2. Create program COSTDPT1 from source file costdpt1.cpp and service program
COST, located in library MYLIB:
iccas /B"CRTPGM PGM(MYLIB/COSTDPT1) BNDSRVPGM(MYLIB/COST)" costdpt1.cpp
3. Update service program COST to include module COST2, using the updated binder
language source BNDUPD, located in source file QSRVSRC in library MYLIB:
iccas /B"CRTSRVPGM SRVPGM(MYLIB/COST) SRCFILE(MYLIB/QSRVSRC)
SRCMBR(BNDUPD) DETAIL(\EXTENDED)" cost1 cost2.cpp
It is necessary to re-create the service program COST, using the two modules
COST1 and COST2 and the updated version of the binder language BNDUPD, so that
it supports the new cost2() function. Program COSTDPT1, which used COST
before it was re-created, remains unchanged.
In order to update service program COST, it is necessary to re-create it from the
two modules COST1 and COST2, using the updated version of the binder language
BNDUPD. The *EXTENDED option in the DETAIL parameter creates an extended
output listing, so that you can look at the current and previous signature of COST.
4. Create program COSTDPT2 from source file costdpt2:
iccas /B"CRTPGM PGM(MYLIB/COSTDPT2) BNDSRVPGM(MYLIB/COST)" costdpt2.cpp

Running the Program


Run program COSTDPT1 from an OS/400 command line using the CL command CALL
COSTDPT1.

Run program COSTDPT2 from an OS/400 command line using the CL command CALL
COSTDPT2.

170 IBM VisualAge C++ for OS/400 C++ User’s Guide


Creating Your Own Make File

11 Creating a Make File

Make files simplify the process of compiling programs composed of several source
files. This chapter describes how to create your own make file for AS/400 applica-
tions compiled from an OS/2 workstation. Topics cover:
Ÿ Creating your own make file
Ÿ Conditions and restrictions when creating make files

An example illustrates the creation of a make file for a simple application.


Note: If you have created a WorkFrame project for your application, you can use
WorkFrame's make-file creation utility MakeMake to create your make files.

See the VisualAge C++ for OS/2 User’s Guide, for information on creating make
files using the MakeMake utility.

Creating Your Own Make File


Using a make file simplifies the task of compiling programs that have more than one
source file, especially when there have been changes to only some of the files. The
make file saves time by performing actions only on the files that have changed, and
on the files that incorporate or depend on these changed files.

A make file is a special text file that contains information about the files in your
application.
Ÿ It describes:
– Which files depend on others
– Which commands such as compile, create program, create service program,
need to be carried out on each file to bring the application up-to-date
Based on this information, the make file determines what actions are to be per-
formed when you need to recompile after having made changes to one or more
files.
Ÿ It compares the modification dates for your target files with the time stamps of
all dependent files.
Note: Make files compare object time stamps. They do not make adjustments
for system-time differences. See “Restrictions When Comparing Time
Stamps” on page 174 for the impact this behavior has in a distributed computing
environment.

 Copyright IBM Corp. 1995 171


Creating Your Own Make File

Ÿ If any dependent files have changed more recently than the target files, a series
of commands specified in the make file are executed.
Ÿ The use of a make file is not limited to compiling and binding. You can also:
– Make backups
– Configure data files
– Run programs when data files are modified
Note: The make process is not tied to the compiler. You can also use it, for
example, to build COBOL or RPG programs.

Format of a Make File


The minimum information to include in a make file is the name of the target file for
compilation, the modules this file depends on, and the command with which you want
to invoke the compiler, as shown in Figure 26:

//Description block

target: dependencies
command

Example:

$(drive)a.pgm: $(drive)a.module $(drive)b.module


iccas /b"crtpgm \curlib/a" a b

Figure 26. Format of a Make File

Note: $(drive) must be replaced with the mounted drive that shadows your AS/400
libraries and files on the OS/2 workstation.

A dependent relationship between files is defined in a description block. The


description block contains commands to bring all components up-to-date. The make
file can contain any number of description blocks.

If a dependency list is very long, you may have to split lines using a backslash (\), as
shown in the following example:

172 IBM VisualAge C++ for OS/400 C++ User’s Guide


Conditions and Restrictions of Make Files

$(drive)a.pgm: $(drive)a.module \
$(drive)b.module \
$(drive)c.module \
$(drive)d.module \
$(drive)e.module \
$(drive)f.module \
iccas /b"crtpgm \curlib/a" a b c d e f

You can include additional information in your make file, such as commands to:
Ÿ Establish a connection between the AS/400 and the OS/2 workstation prior to
compilation
Ÿ Set up your library list on the AS/400
Ÿ Mount a network drive
“Example of a Make File” on page 176 shows how to build a make file that initi-
ates these tasks.

Conditions and Restrictions of Make Files


When working with VisualAge C++ for OS/400, your files are usually scattered
across a number of machines. Source files and intermediate code files may reside on
your OS/2 workstation, while module and program objects are located on an AS/400.
This requires special consideration when you use a make file to selectively recompile
project files. The following conditions and restrictions apply:
Ÿ All AS/400 objects must be visible as files on the OS/2 workstation.
Ÿ Time stamps can only be compared reliably when all files involved are created
and located on the same system, or in the same LAN domain.

Mounting a Host Path as a Network Drive on OS/2


You can use the Client Access for OS/400 utility NET4ðð to mount a host path as a
network drive on OS/2.

The format of the OS/2 command to assign a drive is:


NET4ðð assign [d:] [/p=path] [/h=host]
where
d: is the drive to assign
/p specifies the assign path
/h specifies the server to assign to

Chapter 11. Creating a Make File 173


Conditions and Restrictions of Make Files

Type net4ðð assign /? on an OS/2 command line for a list of other supported
command line formats.

See the Online Client Access Command Reference for additional information.

Restrictions When Comparing Time Stamps


Using make files works well only when the source and the target both reside on the
same system, or in the same LAN domain. Otherwise, time stamp mismatches are
always a possibility.

Time Stamp Mismatches


The time stamps of objects on a mounted drive reflect the moment when the corre-
sponding object was created in AS/400 time, not in OS/2 workstation time. The time
stamp of objects created on the OS/2 workstation reflects when the object was created
in workstation time.

If the AS/400 time is earlier than the OS/2 workstation time, there is a chance that
module objects will appear newer to a make file than they actually are, and conse-
quently, some necessary recompilations may be missed.

If the OS/2 workstation time is earlier than the AS/400 time, there is a chance that
module objects will appear older than they are, and some unnecessary compilations
may take place.

In some cases, it may be possible to synchronize the OS/2 workstation time and the
AS/400 time, although, in most cases, this may lead to problems in other areas. For
example, if two systems are in different time zones, time stamps of file objects may
be misleading, because they reflect local object-creation times. In such cases, syn-
chronization of the two systems would not be useful.

If you are in doubt about whether object time stamps accurately reflect the order in
which objects were created, you should recompile the entire application rather than
rely on a make file.

Synchronizing System Times with CTTTIME


In case you want to synchronize your OS/2 workstation time with the time of the
AS/400 you are connected to, you can use the Create Time (CTTTIME) command.
The syntax for this command is:

55──CTTTIME──┬──────────┬──┬─────────┬─────────────────────────5%
└─/ASnname─┘ └─[SYNCH]─┘

174 IBM VisualAge C++ for OS/400 C++ User’s Guide


Conditions and Restrictions of Make Files

The CTTTIME command takes the following parameters


/ASnname
Identifies the connection you want to use between your OS/2 workstation and an
AS/400.
Specifying /ASnname is optional if you have already set a value for the environ-
ment variable ICCASNAME.
SYNC
The keyword SYNC requests that OS/2 workstation and AS/400 time be synchro-
nized. This keyword is optional.

Results of Specifying the Keyword SYNC


If you specify the keyword SYNC, CTTTIME will change the OS/2 workstation time
to the time of the AS/400 identified by /ASnname. If the synchronization is suc-
cessful, the command returns a return code of zero, which means that the workstation
local time is set to the local time of the host.

If you do not specify the keyword SYNC, CTTTIME will return the difference between
workstation and host time, in seconds ranging from -32766 to +32767. If the
command encountered an error, such as a communication problem between work-
station and host, the return code will be -32767.

The exact value of the return code has no significant meaning. Of more importance
is to know that:
Ÿ A positive return code means that the AS/400 time is ahead of the OS/2 work-
station time
Ÿ A negative return code means that the OS/2 workstation time is ahead of the
AS/400 time
Ÿ A return code Zero indicates that both system times are identical
Note: Calculated time differences and synchronized times are based on the local
time of both systems, including daylight-savings adjustments. The local time will not
be normalized into GMT.

Scope of Synchronizing OS/2 Workstation and the AS/400


Synchronizing OS/2 workstation time and AS/400 system time will only affect objects
created in the future. It will not affect objects created in the past, because they retain
their former time stamp. To solve this problem, you could change the time stamp of
the source file, but this may be difficult, if the source is not located on a local drive.

Attention: Changing the workstation time may create new problems, such as being
out of synchronization with the LAN domain, or causing other existing applications to
fail. The system time might also be changed again by other applications during the
course of the make file processing, which may cause unexpected results.

Chapter 11. Creating a Make File 175


Example of a Make File

Example of a Make File


In the following example, a make file aa.mak contains information that is necessary
to compile (or recompile) two source files, aa.cpp and bb.cpp. The objective is to
build program AA on an AS/400 called SYSAS1.

ALL: STARTUP Z:AA.PGM END

STARTUP:
cttconn /hsysas1 // establish a host connection
ctthcmd call mysetup/b // call to a program that performs specific setup task
ctthcmd chgcurlib mylib// change the current library on the host
ctttime sync // optional synchronization of workstation and host time
z: // change to the appropriate directory of the mounted drive
cd \qsys.lib\mylib.lib
e: // change to the appropriate directory of the workstation drive
cd \sample

Z:AA.PGM: Z:BB.MODULE Z:AA.MODULE // Program AA is to be created from


iccas -q aa bb// modules AA and BB, located on the
// mounted drive Z:
Z:AA.MODULE: aa.cpp
iccas -q -c aa.cpp

Z:BB.MODULE: bb.cpp
iccas -q -c bb.cpp

END:
cttdis // ends the connection established earlier

The source files for this example are shown below:

// aa.cpp
#include <iostream.h>
extern void bb(void);
void main()
{
cout << "Here is program AA" << endl
<< "Calling program BB" << endl;
bb();
cout << "back to program AA" << endl;

#include <iostream.h>
extern void bb(void);
void bb()
{
cout << "Here is program BB" << endl;
}

176 IBM VisualAge C++ for OS/400 C++ User’s Guide


Example of a Make File

To create program AA., invoke the make file by entering nmake aa.mak on an OS/2
command line.

Chapter 11. Creating a Make File 177


Example of a Make File

178 IBM VisualAge C++ for OS/400 C++ User’s Guide


Calling a Program

12 Running a Program

Once you have created an OS/400 program, the next step is to run it on an AS/400
system. So far, most of the development work has been done on your OS/2 work-
station. Now, you must switch to the AS/400 to run your application.
Note: Although you can launch an OS/400 application from an OS/2 window, this
usually does not produce the desired results, because program output is not visible
from the OS/2 workstation.

This chapter describes how to run an AS/400 application. Topic


Ÿ Calling a program using a variety of commands or menus
Ÿ Passing parameters to a program
Ÿ Ending a program
Ÿ Managing activation groups
Ÿ Managing run-time storage

Numerous examples are included to illustrate the above topics.


Note: Only programs can run independently. Service programs, or other bound pro-
cedures, must be called from a program that requires their services.

Calling a Program
When you call a program, the OS/400 system locates the corresponding executable
code and performs the instructions found in the program.

There are several ways to call a program:


Ÿ Issue the CL CALL command
Ÿ Issue the CL Transfer Control (TFRCTL) command
Ÿ Issue a user-created CL command

In addition, you can run a program using:


Ÿ The Programmer Menu
See CL Programmingfor information on this menu.
Ÿ The Start Programming Development Manager (STRPDM) command
See ADTS/400: Programming Development Manager for information on this
command.
Ÿ The EVOKE statement from an ICF file

 Copyright IBM Corp. 1995 179


Calling a Program

See ICF Programming for information on the EVOKE statement.


Ÿ The QCAPEXC program
See CL Programming for information on this program.
Ÿ A high-level language
See the VisualAge C++ for OS/400 C++ Programming Guide for information on
inter-language calls in the Integrated Language Environment. See Chapter 9,
“Creating a Service Program” on page 141 for information on calling service
programs and procedures.
Ÿ The REXX interpreter
See the REXX/400 Programmer’s Guide for information on using REXX/400.

Using the CL CALL Command


From the AS/400 command line, you can use the CALL command to run a program
interactively, or as part of a batch job.

The syntax for this CL command is:

55──CALL PGM──(library-name/program-name)──────────────────────5%

For example, the command


CALL PGM(MYLIB/MYPROG)
invokes the program MYPROG located in the library MYLIB.

If the program object specified by program-name exists in a library that is contained


in your library list, you can omit the library name in the command, and the syntax is:

55──CALL──program-name─────────────────────────────────────────5%

For example, if MYLIB appears in your library list, you can simply type:
CALL MYPROG

If you need prompting for the command parameters, type CALL and press F4
(Prompt). If you need help, type CALL and press F1 (Help).

180 IBM VisualAge C++ for OS/400 C++ User’s Guide


Calling a Program

Example of Calling a Program Using the TFRCTL Command


You can run an application from within a CL program that transfers control to your
program using the Transfer Control (TFRCTL) command. This command:
1. Calls the program specified on the command.
2. Transfers control to the called program
3. Removes the transferring CL program from the call stack.

In the following example, the TFRCTL command in a CL program RUNCP calls a


C++ program XRUN2, which is specified on the TFRCTL command. RUNCP transfers
control to XRUN2. The transferring program RUNCP is removed from the call stack.

Figure 27 illustrates the call to the CL program RUNCP, and the transfer of control to
the C++ program XRUN2.

User Call


6
┌───────────────┐ ┌───────────────┐
│ CL Program │ │ C++ Program │
│ RUNCP │ │ XRUN2 │
│ .... │ │ .... │
│ .... │ │ .... │
│ .... │ │ .... │
│ Control Transfer │ │
│ TRFCTL ───────┼────────────5│ │
│ │ │ │
│ │ │ │
└───────┬───────┘ └───────┬───────┘
│ │
│ │
┌───────┴───────┐ ┌───────┴───────┐
│ removed from │ │ program │
│ call stack │ │ exits │
└───────────────┘ └───────────────┘

Figure 27. Calling Program XRUN2 Using the TFRCTL Command

To create and run programs RUNCP and XRUN2, follow the steps below:
1. Enter the source code shown below into a source physical file QCLSRC, in library
MYLIB.

Chapter 12. Running a Program 181


Calling a Program

/\ Source for CL Program RUNCP \/

PGM PARM(&STRING)
DCL VAR(&STRING) TYPE(\CHAR) LEN(2ð)
DCL VAR(&NULL) TYPE(\CHAR) LEN(1) VALUE(X'ðð')

/\ ADD NULL TERMINATOR FOR THE ILE C++ PROGRAM \/


CHGVAR VAR(&STRING) VALUE(&STRING \TCAT &NULL)

TFRCTL PGM(MYLIB/XRUN2) PARM(&STRING)

/\ THE DSPJOBLOG COMMAND IS NOT CARRIED OUT SINCE \/


/\ WHEN PROGRAM XRRUN2 RETURNS, IT DOES NOT RETURN TO THIS \/
/\ CL PROGRAM. \/

DSPJOBLOG

ENDPGM

2. Create the CL program RUNCP. From an OS/2 command line, specify:


CTTHCMD CRTCLPGM PGM(MYLIB/RUNCP) SRCFILE(MYLIB/QCLSRC)
If you prefer to create the program from the AS/400 command line, type:
CRTCLPGM PGM(MYLIB/RUNCP) SRCFILE(MYLIB/QCLSRC)
Program RUNCP uses the TFRCTL command to pass control to the ILE C++
program XRUN2, which does not return to RUNCP.
3. Create program XRUN2 in library MYLIB from the source file xrun2.cpp shown
below:

// xrun2.cpp
// Source for Program XRUN2
// Receives and prints a null-terminated character string

#include <iostream.h>

int main(int argc, char \argv[])


{
int i;
char \ string;
string = argv[1];
cout << "string = " << string << endl;
}

On an OS/2 command line type:


iccas /ASlmylib xrun2.cpp

182 IBM VisualAge C++ for OS/400 C++ User’s Guide


Calling a Program

Program XRUN2 receives a null terminated character string from the CL program
and prints the string.
4. Run program XRUN2 from an AS/400 command line, passing it the string "nails",
with the command:
CALL PGM(MYLIB/RUNCP) PARM('nails')
The output from program XRUN2 is:

à@ ð
string = nails
Press ENTER to end terminal session.
á ñ
Example of Running a Program from a User-Created CL Command
You can also run a program from your own CL command. To create a command:
1. Enter a set of command statements into a source file.
2. Process the source file and create a command object (type \CMD) using the Create
Command (CRTCMD) command.
The CRTCMD command definition includes the command name, parameter
descriptions, and validity-checking information, and identifies the program that
performs the function requested by the command.
3. Enter the command interactively, or in a batch job.
The program called by your CL command is run.

See CL Programming for further information about using commands.

The following example illustrates how to run a program from a user-created CL


command:

Program Description
A newly created command COST prompts for and accepts user input values. It then
calls a C++ program CALCOST and passes it the input values. CALCOST accepts the
input values from the command COST, performs calculations on these values, and
prints results. Figure 28 on page 184 illustrates this example.

Chapter 12. Running a Program 183


Calling a Program

Command
┌────────────────────────────┐
│ COST │
│----------------------------│
│. Prompts for user input │
│ │
│. Accepts user-input values │
│ │
│. Calls program CALCOST and │
│ passes input values to it │
└────────────────────────────┘

C++ Program
┌────────────────────────────┐
│ CALCOST │
│----------------------------│
│. Processes input values │
│ │
│. Performs calculations │
│ │
│. Produces printed output │
└────────────────────────────┘

Figure 28. Calling Program CALCOST from a User-Defined Command COST

To create and run the example, follow the steps below:


1. Enter the source code for the command prompt COST shown below into a source
file QCMDSRC in library MYLIB:

/\ Source for Command Prompt COST

CMD PROMPT('CALCULATE TOTAL COST')


PARM KWD(ITEM) TYPE(\CHAR) LEN(2ð) RSTD(\NO) +
MIN(1) ALWUNPRT(\NO) PROMPT('Item name' 1)
PARM KWD(PRICE) TYPE(\DEC) LEN(1ð 2) RSTD(\NO) +
RANGE(ð.ð1 99999999.99) MIN(1) +
ALWUNPRT(\YES) PROMPT('Unit price' 2)
PARM KWD(QUANTITY) TYPE(\INT2) RSTD(\NO) RANGE(1 +
9999) MIN(1) ALWUNPRT(\YES) +
PROMPT('Number of items' 3)

2. Create the CL command prompt COST. On an AS/400 command line, enter:


CRTCMD CMD(MYLIB/COST) PGM(MYLIB/CALCOST) SRCFILE(MYLIB/QCMDSRC)
or on an OS/2 command line enter:
CTTHCMD CRTCMD CMD(MYLIB/COST) PGM(MYLIB/CALCOST) SRCFILE(MYLIB/QCMDSRC)

184 IBM VisualAge C++ for OS/400 C++ User’s Guide


Calling a Program

Use the CL command prompt COST to enter item name, price, and quantity for
the ILE C++ program CALCOST.
3. Create program CALCOST from the source file calcost.cpp shown below:

// calcost.cpp
// Source for Program CALCOST

#include <iostream.h>
#include <string.h>
#include <bcd.h>

int main(int argc, char \argv[])


{
char \item_name;
_DecimalT<1ð,2> \price;
short int \quantity;
const _DecimalT<2,2> taxrate=__D("ð.15");
_DecimalT<17,2> cost;

item_name = argv[1];
price = (_DecimalT<1ð,2> \) argv[2];
quantity = (short \) argv[3];

cost = (\quantity)\(\price)\(&us_.D"1.ðð"+taxrate);

cout << "\nIt costs $" << cost << " to buy "
<< \quantity << " " << item_name << endl;
}

This program receives the incoming arguments from the CL command COST, cal-
culates a cost, and prints values. All incoming arguments are pointers.
To compile and bind source filexrun2.cpp, invoke the compiler from an OS/2
command line using the command:
iccas /B"crtpgm(mylib/calcost) output(\print)" calcost.cpp
4. Enter data for the program CALCOST. From the AS/400 command line, type COST
and press F4 (Prompt).
Type the data shown below into COST:

Hammers
1.98
5ððð

Nails
ð.25
2ððð

Chapter 12. Running a Program 185


Passing Parameters to a Program

The output of program CALCOST is:

à@ ð
It costs $11385.ðð to buy 5ððð HAMMERS
Press ENTER to end terminal session.
>

It costs $575.ðð to buy 2ððð NAILS


Press ENTER to end terminal session.

á ñ

Passing Parameters to a Program


To pass parameters to an ILE program when you run it, use the PARM option of the
CL CALL command. The syntax for this command is:
CALL PGM(program-name) PARM(param-1 param-2 ... param-n)

You can also type the parameters without specifying any keywords:
CALL library/program-name (param-1 param-2 ... param-n)

The following example demonstrates how to pass the value 'Hello, World' to
program XRUN1 which expects parameters at run time. The source file xrun1.cpp for
program XRUN1 is shown below:

// xrun1.cpp
// Prints out command line arguments.
#include <iostream.h>

int main ( int argc, char \argv[] )


{
int i;
for ( i = 1; i < argc; ++i )
cout << argv[i] << endl;
}

Follow the steps below, to create and run program XRUN1:


1. Ensure that you have established a connection between your workstation and an
AS/400 system.
2. Compile the source shown above with default compiler options. On the OS/2
command line type:
iccas xrun1.cpp
The resulting module and program objects are created into the default library on
the AS/400, in this example, MYLIB.

186 IBM VisualAge C++ for OS/400 C++ User’s Guide


Passing Parameters to a Program

3. Run the program from an AS/400 command line using the command:
CALL PGM(MYLIB/XRUN1) PARM('Hello, World')
The output of program XRUN1 is:

à@ ð
Hello, World
Press ENTER to end terminal session.
á ñ
Note: If you run the same program from an OS/2 command line, using the
command:
CTTHCMD /ASnmycon CALL PGM(MYLIB/XRUN1) PARM('Hello World')
the output is sent to a spool file QPRINT on the AS/400, and is not visible on the
OS/2 workstation.

Processing Parameters
When you call a program from a CL command line, the parameters you pass on the
CALL command are changed as follows:
Ÿ String literals passed are terminated by a null character.
Ÿ Numeric constants are passed as binary coded decimal digits.
Ÿ Characters that are not enclosed in single quotation marks are folded to uppercase
and are passed with a null character.
Ÿ Characters that are enclosed in single quotation marks are not changed, and
mixed-case strings are supported and are passed with a null character.
Figure 29. Parameter Conversion from a CL Command to a Program

CL Call Command Parameter Conversion


Received
CALL PGM(XRUN1) PARM(abc) ABC\0 (converted to uppercase;
passed as a string)
CALL PGM(XRUN1) PARM('123.4') 123.4\0 (passed as a string)
CALL PGM(XRUN1) PARM(123.4) 123.4 (passed as binary coded
decimal digits (15,5))
CALL PGM(XRUN1) PARM('abc') abc\0 (passed as a string)
CALL PGM(XRUN1) PARM('abC') abC\0 (passed as a string)

Note: These changes only apply when you call a program from a command line, not
to interlanguage calls.

Chapter 12. Running a Program 187


Managing Activation Groups

See the VisualAge C++ for OS/400 C++ Programming Guide for information on
interlanguage calls.

Ending a Program
When a program ends normally, the system returns control to the caller. The caller
could be a workstation user or another program.

If a program ends abnormally during run time, and the program had been running in a
different activation group from its caller, the escape message CEE9901 is issued and
control is returned to the caller:

à@ ð
Application error <msgid> unmonitored by <pgm> at
statement <stmtid>, instruction <instruction>
á ñ
A CL program can monitor for this exception by using the Monitor Message
(MONMSG) command.

See the CL Reference for more information about such CL commands.

If the program is running in the same activation group as is its caller and the program
ends abnormally, what message is issued depends on how the program ended. If it
ended with a function check, CPF9999 is issued. If the exception is issued by a C++
procedure, it has a message prefix of CTT.

See the VisualAge C++ for OS/400 C++ Programming Guide for more information
on exception messages.

Managing Activation Groups


Activation groups make it possible for multiple ILE programs to run in the same job
independently, without intruding on each other.

An activation group is a substructure of a job. It consists of system resources such as


storage, commitment definitions, and open files. These resources are allocated to run
one or more ILE or OPM programs. For example, the storage space for the static
variables of a program is allocated from an activation group.

Once a program (type \PGM) is called, it remains activated until the activation group it
runs in is deleted. Because service programs are not called directly, they are acti-
vated during the call to the program that requires their services.

188 IBM VisualAge C++ for OS/400 C++ User’s Guide


Managing Activation Groups

See ILE Concepts for additional information on program activation.

Specifying an Activation Group


When an OS/400 job is started, the system automatically creates two activation
groups to be used by OPM programs. One activation group is reserved for OS/400
system code. The other activation group is used for all other OPM programs. The
symbol used to represent this activation group is *DFTACTGRP. You cannot delete
the OPM default activation groups. The system deletes them when your job ends.
Note: OPM programs always run in the default activation group; you cannot change
their activation group specification.

For ILE programs you specify the activation group that should be used at run time
through the ACTGRP parameter of the Create Program or Create Service Program
commands. You can choose between:
Ÿ Running your program in an activation group named by you
Ÿ Accepting the default activation group *NEW, named by the system
Ÿ Activating a program into the activation group of a calling program

Running a Program in a Named Activation Group


To manage a collection of ILE programs and service programs as one application,
you create a named activation group for them by specifying a user-defined name on
the ACTGRP parameter.

The system creates the named activation group as soon as the first program that has
specified this activation group is called. This group is then used by all programs and
service programs that have specified its name.

A named activation group ends when it is deleted through the Reclaim Activation
Group (RCLACTGRP) command. This command can only be used when the acti-
vation group is no longer in use. It also ends when you call the exit() function in
your code.

When a named activation group ends, all resources associated with the programs and
service programs of the group are returned to the system.

Attention: Using named activation groups may result in non-ANSI compliant run-
time behavior. If a C++ programs created using named activation groups remains
activated by a return statement, you encounter the following problems:
Ÿ Static variables will not be reinitialized
Ÿ Static constructors will not be called again
Ÿ Static destructors will not be called on return

Chapter 12. Running a Program 189


Managing Activation Groups

Ÿ Other programs activated in the same activation group may terminate your
program, although they seem to be independent
Ÿ Your program is not portable, if you count on the behavior of the named acti-
vation group.

In the following example, programs PROG1, PROG2, and PROG3 are part of the same
application and run in the same activation group, GROUP1. Figure 30 illustrates this
scenario:

ACTGRP GROUP1

PROG1

PROG2

PROG3

Figure 30. Running Programs in A Named Activation Group

To create these programs into the same activation group, you specify GROUP1 on the
ACTGRP parameter when you create each program:

iccas /B"crtpgm pgm(prog1) actgrp(group1)" prog1.cpp


iccas /B"crtpgm pgm(prog1) actgrp(group1)" prog2.cpp
iccas /B"crtpgm pgm(prog1) actgrp(group1)" prog3.cpp

Running a Program in Activation Group *NEW


To create a new activation group whenever your program is called, specify *NEW on
the ACTGRP parameter. In this case, the system creates a name for the activation
group that is unique within your job. *NEW is the default value of the ACTGRP
parameter on the CRTPGM command.

An activation group created with *NEW always ends when the last program associated
with it ends.
Note: *NEW is not valid for a service program, which can only ru in the activation
group of its caller, or in a named activation group.

If you create an ILE C++ program with ACTGRP(*NEW), you can call the program as
many times as you want, without returning from earlier calls. With each call, you use

190 IBM VisualAge C++ for OS/400 C++ User’s Guide


Managing Activation Groups

a new copy of the program. Each new copy has its own data and opens its files.
However, you must code some way for the program to end these recursive calls to
itself; otherwise, you will keep creating new activation groups and the program will
never return.

In the following example, programs PROG4, PROG5, and PROG6 run in separate
unnamed activation groups. Figure 31 illustrates this scenario:

ACTGRP *NEW

PROG4

ACTGRP *NEW

PROG5

ACTGRP *NEW

PROG6

Figure 31. Running Programs in Unnamed Activation Groups

By default, each program is created into a different activation group, identified by the
ACTGRP parameter (*NEW).

iccas /B"crtpgm pgm(prog4) actgrp(\NEW)" prog4.cpp


iccas /B"crtpgm pgm(prog5) actgrp(\NEW)" prog5.cpp
iccas /B"crtpgm pgm(prog6) actgrp(\NEW)" prog6.cpp

Because *NEW is the default, you obtain the same result with the following
invocationscolon.
iccas /B"crtpgm pgm(prog4)" prog4.cpp
iccas /B"crtpgm pgm(prog5)" prog5.cpp
iccas /B"crtpgm pgm(prog6)" prog6.cpp
Note: If you invoke all three source files in one command, a single program object
PROG is created in activation group *NEW:
iccas /B"crtpgm pgm(prog) actgrp(group1)" prog4.cpp prog4.cpp prog6.cpp

Running a Program in Activation Group (*CALLER)


To run a program or service program in the activation group of a calling program,
specify *CALLER on the ACTGRP parameter.

If an ILE program created with ACTGRP(*CALLER) is called by an OPM program, it is


activated into the OPM default activation group (*DFTACTGRP).

Chapter 12. Running a Program 191


Managing Activation Groups

In the following example, a service program SRV1 is activated into the respective acti-
vation groups of programs PROG7 and PROG8. PROG7 runs in a named activation
group GROUP2, while PROG8 runs in an unnamed activation group *NEW. Figure 32 on
page 192 illustrates this scenario:

ACTGRP GROUP2
PROG7

SRV1

ACTGRP *NEW
PROG8

SRV1

Figure 32. Running a Service Program in the Activation Groups of Calling Programs

By default,the service program SRV1 is created into the activation group of each
calling program.
iccas /B"crtsrvpgm srvpgm(srv1)" srv1.cpp

Presence of a Program on the Call Stack


Even though it is activated, a program does not appear on the call stack unless it is
running. But an activation group can continue to exist even when the main() function
of the program is not on the call stack.

This occurs when the program was created with a named activation group, and the
main() function issues a return. It can also occur when the program performs a
longjmp() across a control boundary by using a jump buffer that is set in an ILE
C++ procedure. (This procedure is higher in the call stack and before the nearest
control boundary.)

See ILE Concepts for information on control boundaries.

Deleting an Activation Group


When an activation group is deleted, its resources are reclaimed. The resources
include static storage and open files. A *NEW activation group is deleted when the
program it is associated with returns to its caller.

Named activation groups are persistent. You must delete them explicitly. Otherwise
they will end only when the job ends. The storage associated with programs running
in named activation groups is not released until these activation groups are deleted.

192 IBM VisualAge C++ for OS/400 C++ User’s Guide


Managing Activation Groups

The OPM default activation group is also a persistent activation group. The storage
associated with ILE programs running in the default activation group is released
either when you sign off (for an interactive job) or when the job ends (for a batch
job).

Reclaiming System Resources


You may encounter situations where system storage is exhausted, for example:
Ÿ If many ILE programs are activated (that is, called at least once)
Ÿ If ILE programs that use large amounts of static storage run in the OPM default
activation group (storage will not be reclaimed until the job ends).
Ÿ If many service programs are called into named activation groups (resources are
only reclaimed when the job ends)

In such situations, you may want to reclaim system resources that are no longer
needed for a program, but are still tied up because an activation group has not been
deleted. You have the following options:
Ÿ You can create an ILE program with the parameter DFTACTGRP(*YES).
In this case, the program's storage is released when the program ends.
Ÿ You can delete a named activation group that is not in use through the Reclaim
Activation Group (RCLACTGRP) command .
The command provides options to either delete all eligible activation groups or to
delete an activation group by name.
See the CL Reference for more information on RCLACTGRP.
Ÿ Free resources for programs that are no longer active through the Reclaim
Resources (RCLRSC) command.

Using the Reclaim Resources Command (RCLRSC)


The RCLRSC command works differently depending on how the program was
created:
Ÿ If the program is an OPM program or was created using DFTACTGRP(*YES), the
RCLRSC command closes open files and frees static storage.
Ÿ For ILE programs that were activated into the OPM default activation group
because they were created with *CALLER, files are closed and storage re-
initialized when the RCLRSC command is issued. However, the storage is not
released.
Ÿ For ILE programs associated with a named activation group, the RCLRSC
command has no effect. You must use the RCLACTGRP command to free
resources in a named activation group.

Chapter 12. Running a Program 193


Managing Activation Groups

See CL Reference for more information on the RCLRSC command. See ILE
Concepts for more information on the RCLRSC and activation groups.

Run-Time Compliance with ANSI C++ Draft Semantics


The ILE C++ run-time model complies with ANSI C++ Draft semantics when all pro-
grams in an application are created with the following options on the CRTPGM
command:
ACTGRP(*NEW) A new activation group is created on every call of the
program, and the activation group is destroyed when
the program is terminated.
OPTION(*NODUPPROC) No duplicate procedure definitions in the same bound
program are allowed.
OPTION(*NODUPVAR) No duplicate variable definitions in the same bound
program are allowed.

ILE C++ Run-Time Library Functions


All programs activated in the same activation group share one instance of the run-
time library, because the ILE C++ run-time library functions are bound to an applica-
tion in the same activation group in which it is called.

The state of the run time propagates across program call boundaries. That is, if one
program in an activation group changes the state of the run time (for example, the
locale setting of an application), other programs in the same activation group are
affected.

Non-ANSI Behavior with Named Activation Groups


If the ACTGRP parameter of the CRTPGM command is specified as a value other than
*NEW, the application's run-time behavior may not follow ANSI semantics.
Non-ANSI behavior may occur during:
Ÿ Program termination - exit(), abort(), atexit()
Ÿ Signal handling - signal(), raise()
Ÿ Multibyte string handling - mblen()
Ÿ Any locale-dependent library functions - isalpha(), qsort()

In the default activation groups, I/O files are not automatically closed. The I/O
buffers are not flushed unless explicitly requested.

Activation Within the Activation Group of a Calling Program


You can specify that an ILE program or an ILE service program be activated within
the activation group of a calling program, by setting ACTGRP to *CALLER. With this
attribute, a new activation group is never created when the program or service
program is activated. Through this option, ILE C++ programs can run within the
OPM default activation groups when the caller is an OPM program.

194 IBM VisualAge C++ for OS/400 C++ User’s Guide


Managing Run-Time Storage

Certain restrictions exist for ILE C++ programs running in the OPM default activation
groups. For example, you are not allowed to register atexit() functions within the
OPM default activation groups.

If the activation group is named, all calls to programs in this activation group within
the same job share the same instance of the ILE C++ run-time library state.

It is possible to create an ANSI-compliant application whose programs are created


with options other than ACTGRP(*NEW). However, it is the responsibility of the appli-
cation designer to ensure that the sharing of resources and run-time states across all
programs in the activation group do not result in non-ANSI behavior.

Managing Run-Time Storage


ILE allows you to directly manage run-time storage from your program, by managing
heaps. A heap is an area of storage used for allocations of dynamic storage. The
amount of dynamic storage required by an application depends on the data being
processed by the programs and procedures that use the heap. You manage heaps by
using ILE bindable APIs.

You are not required to explicitly manage run-time storage. However, you may wish
to do so if you want to make use of dynamically allocated storage, for example, if
you do not know exactly how big an array should be. In this case you could acquire
the actual storage for the array at runtime, once your program determines how big the
array should be.

There are two types of heaps available on the system:


Ÿ The default heap
Ÿ A user-created heap.

You can use one or more user-created heaps to isolate the dynamic storage required
by some programs and procedures within an activation group.

The rest of this section explains how to use a default heap to manage run-time
storage in a C++ program.

See ILE Concepts. for information on creating a user-created heap and other ILE
storage-management concepts.

Managing the Default Heap


The first request for dynamic storage within an activation group results in the creation
of a default heap from which the storage allocation takes place. Additional requests
for dynamic storage are met by further allocations from the default heap. If there is

Chapter 12. Running a Program 195


Managing Run-Time Storage

insufficient storage in the heap to satisfy the current request for dynamic storage, the
heap is extended, and the additional storage is allocated.

Allocated dynamic storage remains allocated until it is explicitly freed, or until the
heap is discarded. The default heap is discarded only when the owning activation
group ends.

Programs in the same activation group all use the same default heap. If one program
accesses storage beyond what has been allocated, it can cause problems for another
program.

For example, assume that two programs, PGM1 and PGM2 are running in the same
activation group. 10 bytes are allocated for PGM1, but 11 bytes are changed by it. If
the extra byte was in fact allocated for PGM2 problems may arise for PGM2.

Using Bindable APIs to Manage the Default Heap


You can use the following ILE bindable APIs on the default heap:
Free Storage (CEEFRST)
This bindable API frees one previous allocation of heap storage
Get Heap Storage (CEEGTST)
This bindable API allocates storage within a heap
Reallocate Storage (CEECZST)
This bindable API changes the size of previously allocated storage
Note: You cannot use these or any other ILE bindable APIs from within a program
created with DFTACTGRP(*YES). This is because static binding is not allowed in this
type of program.

See the System API Reference for specific information about the storage-
management bindable APIs.

Dynamically Allocating Storage at Run Time


In an ILE C++ program, you manage dynamic storage belonging to the default heap
using the operators new and delete to create and delete dynamic objects. Dynamic
objects are never created and deleted automatically. Their creation can fail if there is
not enough free heap space available, and your programs must provide for this possi-
bility.

The following examples illustrate dynamic storage allocation with new and delete:
1. Dynamic allocation and de-allocation of storage for a class object:

196 IBM VisualAge C++ for OS/400 C++ User’s Guide


Managing Run-Time Storage

TClass \p; // Define pointer


p= new TClass; // Construct object

if (!p) {
Error("Unable to construct object");
exit(1);
}
...
delete p; // Delete object
2. Dynamic allocation and de-allocation of storage for an array of objects:

TClass \array // Define pointer


array = new TClass[1ðð];// Construct array of 1ðð objects

...
delete[] array; // Delete array
Note: In this example, you use delete[] to delete the array. Without the brackets,
delete deletes the entire array, but calls the destructor only for the first element in
the array. If you have an array of values that do not have destructors, you can use
delete or delete[].

Chapter 12. Running a Program 197


Managing Run-Time Storage

198 IBM VisualAge C++ for OS/400 C++ User’s Guide


Part 4. Debugging Your Program
The chapters in this part describe how to debug AS/400 applications from your OS/2
workstation using the Cooperative Debugger, or from the AS/400 using the ILE
Source-Level Debugger. Topics cover:
Ÿ Using the Cooperative Debugger
Ÿ Introducing the primary debugger windows
Ÿ Introducing the secondary debugger windows
Ÿ Using the ILE source-level debugger

 Copyright IBM Corp. 1995 199


200 IBM VisualAge C++ for OS/400 C++ User’s Guide
Preparing for Debugging

13 Using the IBM VisualAge C++ for OS/400 Debugger

The IBM VisualAge C++ for OS/400 Debugger (hereafter called the debugger) is a
client/server program that helps you detect and diagnose errors in code developed
with AS/400 ILE languages. You can , for example, run your program, set break-
points, step through program instructions, examine variables, and examine the call
stack.

This chapter lists the considerations you need to be aware of, and preparatory items
you should complete, before you run the debugger on your program. Topics include:
Ÿ Preparing for debugging
Ÿ Starting a debugging session
Ÿ Ending a debugging session
Ÿ Locating source code
Ÿ Frequently used features of the debugger

Preparing for Debugging


Before you can run the debugger on an OS/400 application, you must perform the
following tasks:
Ÿ Starting the debugger
Ÿ Starting the debug server
Ÿ Setting up a debugger port
Ÿ Compiling a program for debugging
Ÿ Setting environment variables for the debugger

At the end of your debugging session, you must end the debug server.

To perform most of these tasks, your user profile must have the appropriate authori-
ties.

Authorities Required for Using the Debugger


The user profile that you use to sign on to an AS/400 system from the debugger must
have the following authorities:
Ÿ *USE authority to the Start Debug (STRDBG) command
Ÿ *USE authority to the End Debug (ENDDBG) command

 Copyright IBM Corp. 1995 201


Preparing for Debugging

Ÿ *Use authority to the Start Service Job (STRSRVJOB) command


Ÿ *USE authority to the End Service Job (ENDSRVJOB) command
Ÿ Either *CHANGE authority to the program being debugged, or *USE authority to
the program being debugged and *SERVICE special authority.

If the job that you are debugging is running under a different user profile than the
user profile you use to sign on to the AS/400 system from the debugger, the user
profile that you use to sign on to the AS/400 system from the debugger must have the
following authorities:
Ÿ *USE authority to the user profile that the job you are debugging is running
under.
Ÿ *JOBCTL special authority if you do not explicitly use fully qualified program
names (library/program). In other words, if you use *CURLIB or *LIBL or you
do not specify a library name, you need to have *JOBCTL special authority.

The group profile QPGMR will give a user the correct authority to the STRDBG,
ENDDBG, STRSRVJOB, and ENDSRVJOB commands and *JOBCTL special
authority.

Configuring the Debugger


Because the debugger is a client/server program, a method of communication is
required to allow the client and server to communicate. The debugger uses the
sockets programming services for communication. Sockets can be used over either
TCP/IP or APPC using AnyNet support provided by the AS/400 and OS/2 Communi-
cations Manager. An OS/2 debugger client must know the name of the host where
the debugger server and your application will run.

Starting the Debug Server


Before you can use the debugger, the debug server must be started on the AS/400
with the Start Debug Server (STRDBGSVR) command.

Setting Debugger Ports


The debugger client and server communicate with each other using TCP sockets.
TCP sockets communicate through ports. When shipped, the debug server is set up
to listen for connection requests on TCP port 3001. If port 3001 is being used by
another application, you can change it by using the Work Server Table
(WRKSRVTBLE) command on the AS/400. To change the port used by the server,
modify the port called QDBGSVR. Then set the ICCASDBGPORT environment var-
iable on all debugger clients to match the port specified on the WRKSRVTBLE
command. For information on environment variables, see “Setting Environment
Variables for Debugging” on page 203.

202 IBM VisualAge C++ for OS/400 C++ User’s Guide


Preparing for Debugging

Note: Before changing the port, end the debug server by using the End Debug
Server (ENDDBGSVR) command. Then change the port and start the debug server
again.

Ending the Debug Server


The debug server can be ended using the End Debug Server (ENDDBGSVR)
command. This prevents any new debug sessions from starting, but active sessions
continue until completion or until they are cancelled.

Compiling Your C++ Program


To use the debugger, compile and bind your C++ program with one of the following
options:
/Ti+ Compiles your program to produce a module that includes a source
view, a listing view, and a statement view for debugging purposes.
/Til Compiles your program to produce a module that includes a listing
view and a statement view for debugging purposes.
/Tis: Compiles your program to produce a module that includes a source
view and a statement view for debugging purposes.

Compiling ILE Languages Other than C++


If you will be debugging programs written in ILE languages other than C++, see the
appropriate language manual for compiling with debug data.

Optimization and Debugging


Generally, the higher the optimization level, the more efficiently the procedures in the
module run. However, higher optimization levels also adversely affect the accuracy
of variables when they are displayed or changed with the debugger.

While debugging your code, set the optimization level to the minimum level (*NONE).
This allows you to accurately display and change variables. After you have com-
pleted your debugging session, set the optimization level to the maximum level. This
provides the highest levels of performance for the procedures in the module.
Note: Even at optimization level *NONE, some optimization may be done in certain
cases that could affect the debugger’s ability to accurately display the program’s
stopped location.

Setting Environment Variables for Debugging


You can use several environment variables with the debugger. The following envi-
ronment variables may be set for use with the debugger:

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 203
Preparing for Debugging

ICCASDEBUGHOST The name of the host. ICCASDEBUGHOST is an


optional environment variable. If you do not use
ICCASDEBUGHOST, you must use the /e command
line parameter when you invoke the debugger.
ICCASTAB The number of spaces per tab. ICCASTAB is an
optional environment variable.
ICCASUPRD Whether to allow the update of production files.
ICCASUPRD is an optional environment variable.
ICCASDEBUGPATH The search paths for the source code files.
ICCASDEBUGPATH is an optional environment vari-
able.
ICCASDBGPORT The port used to connect to the AS/400.
ICCASDBGPORT is an optional environment variable.

To set the AS/400 environment for the debugger, type the following at the OS/2
command prompt:
SET ICCASDEBUGHOST=debughostname
where debughostame is the IP address of the AS/400 system you want to debug on,
for example:
SET ICCASDEBUGHOST=IBMAS999

To (determine the IP address of your AS/400, type GO CFGTCP on an AS/400


command line, and choose menu option 12.)

To set tab stops at particular intervals, type the following at the OS/2 command
prompt:
SET ICCASTAB=number
where number is between 1 and 64 inclusive. If ICCASTAB is not set, the default is
8. For example, SET ICCASTAB=5 will cause text after a tab to begin in columns 6,
11, 16, 21, 26, and so on.

To allow the update of production files, type the following at the OS/2 command
prompt:
SET ICCASUPRD=Y
where Y allows production files to be updated, and N does not allow production files
to be updated.

To set the search path for the source code file used by the debugger, type the fol-
lowing at the OS/2 command prompt:
SET ICCASDEBUGPATH=path1;path2;

204 IBM VisualAge C++ for OS/400 C++ User’s Guide


Starting a Debugging Session

where path\ is the path, including the drive and library names, to the location where
the source code files are stored. Multiple paths must be separated with semicolons.

To connect to the AS/400 using a port other than the default port, type the following
at the OS/2 command prompt:
SET ICCASDBGPORT=port number
where port number is a value between 1 and 64,767 that matches the port number
specified for the QDBGSVR entry on the AS/400.

Starting a Debugging Session


This section explains how to:
Ÿ Start a debugging session
Ÿ End a debugging session
Ÿ How to locate source code.

Starting the Debugger from an OS/2 Prompt


To start the debugger from the OS/2 command prompt, perform the following steps:
1. Compile your code requesting one or more of the debugging views (*TEXT,
*LISTING, *STATEMENT). See “Compiling Your C++ Program” on
page 203.
2. Bind the program.
3. Ensure that the debug server is running on the AS/400.
See “Starting the Debug Server” on page 202 for details.
4. Ensure that the ICCASDEBUGHOST environment variable is set.
5. Start the debugger on your OS/2 workstation by entering the debugger invocation
command ipmdas. You can use parameters with this command by typing
ipmdas /x program-name
where /x represents any number of debugger parameters. Choose from the fol-
lowing debugger parameters:
/a Run the program, but do not stop at main. The program runs until it com-
pletes or comes to a breakpoint. This parameter has the same function as
the shortcut keys CTRL + R.
/e Specify the name of the host system that you want to connect to for your
debugging session. If the /e parameter is not used, the host name specified
in the ICCASDEBUGHOST environment variable is used.

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 205
Starting a Debugging Session

/i Step into the program, but do not run to main. This parameter has the
same function as the Step into program check box on the Startup Infor-
mation window.
/j Specify a job name, which requires the job-name operand. Job name is
specified as it is on the Startup Information window. No spaces should
be placed between the /j parameter and the job-name operand. The correct
format is /jjob-name.
If you specify the /j parameter and the program name, you will bypass the
Startup Information window.
/p+ Use program profile information, if program profile information is avail-
able. This is the default.
/p- Do not use any program profile information.
The Startup Information window is shown below:

Figure 33. Startup Information Window

6. In the Program entry field, either type the name of the program you want to
debug, or click on the down arrow on the Program entry field and select a
program.
7. In the Job name entry field, type the name of the AS/400 job you will use when
the program to be debugged is run. Often, this is the job associated with a 5250
terminal session, but it can be any AS/400 server job, a batch job, a prestarted
job, or an evoked job. If you select Jobs list, the Jobs List window is shown.
From this window, select the job you want and select OK. The Startup Infor-
mation window is shown again with the job name you selected displayed in the
Job name entry field.

206 IBM VisualAge C++ for OS/400 C++ User’s Guide


Enable the Use program profile check box to restore the debugger windows and
breakpoints when debugging a program more than once. The program profile is
stored separately for each program debugged.
Enable the Step into program check box to stop your program at the next
runnable statement encountered. Use this option to debug C++ constructors for
objects that are located in static storage or to debug a program that is already
running.
8. Select OK to accept the information you have entered, close the window, and
start the debugger. A debugger message is shown that asks you to start the
program to be debugged on the AS/400.
9. After starting the program on the AS/400, select OK to continue.

Starting the Debugger from WorkFrame


If you have already created a WorkFrame project that contains the files for the
application you are working on, see “Debugging an OS/400 Application” on page 27
for details on how to invoke the Debug action.

If you have not yet created a project for your application and need help, see
Part 1, “Developing OS/400 Applications with WorkFrame” on page 1 first.

Ending the Debugging Session


End the debugging session in one of the following ways:
Ÿ Press F3 in any of the debugger windows
Ÿ Select Close debugger from the File menu-bar choice in a debugger window
Ÿ If no debugger window is open, press Ctrl-C in the OS/2 command window from
which you started the debugger. (If you started the debugger using an icon, click
on that same icon again to bring up the OS/2 command window.)
This may happen after you pressed the OK push button on the Startup Informa-
tion window, but before the Debug Session Control window displays.

You may want to end the debugger session in one of the following situations:
Ÿ In the Startup Information window, you specify the name of a job that is an
active AS/400 job, but it is not the job that you wanted to use.
Ÿ You specify the name of a program on the Startup Information window, but the
program fails when you call it (for example, a signature violation occurs when
you call the program).
Ÿ The job ends on the AS/400 before the startup program is called.

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 207
Locating Source Code

Locating Source Code


How the debugger locates source code depends on whether the source was written in
C++ or another ILE language.

C++ Source Code


When you compile a C++ program and specify the source debug view by using the
/Ti+ option, the compiler stores the name of the source file and its directory path in
the module object. When you try to display the source file, the debugger tries to find
the file using the directory path and file name that was captured when the program
was compiled. The debugger searches for the file in this order:
1. In the directory path that was stored when the module was compiled.
2. In the directory where the last file, if any, was found.
3. In the directories defined in the ICCASDEBUGPATH environment variable.

If the file is not found in any of these directories, you will be prompted for the name
of the file. If the source file is not available, press the Cancel push button on the file
prompt and a different view will be used.

Source Code Written in Other ILE Languages


When you compile other ILE language modules (C, RPG, COBOL, and CL), the
name of the AS/400 source member is stored in the module object. When you try to
display the source for a module, the debugger attempts to read the information from
the AS/400 source member used to create the module.

If the source member is not found, the debugger searches your workstation for a
source file using the following steps:
1. The debugger builds a name using the module name and a file extension based
on the language. The file extensions used are as follows:
RPG For ILE RPG language modules
C For ILE C language modules
CBL For ILE COBOL language modules
CL For ILE CL language modules.
2. The debugger searches for the file in this order:
a. In the directory where the last file, if any, was found.
b. In the directories listed in the ICCASDEBUGPATH environment variable.
If the file is not found, you are prompted to enter the name of the file. If you do
not have the source available, press the Cancel push button on the file prompt
and a different view will be used.

208 IBM VisualAge C++ for OS/400 C++ User’s Guide


Frequently Used Features of the Debugger

Frequently Used Features of the Debugger


This section introduces
Ÿ The title bar buttons
Ÿ Ways to run your program
Ÿ How to set breakpoints
Ÿ The use of multiple statements in program code
Ÿ Debugger performance considerations
Ÿ Debugger limits

Using the Title Bar Buttons


Buttons have been provided for easier access to frequently used features. Check the
title bar on each window to determine which buttons are active for the window.

Step over runs the current, highlighted line in the program, but does
not enter any called procedure. If the current line is a call, the
program is halted when the call is completed.

Step debug runs the current, highlighted line in the program. The
debugger steps over any procedure for which debugging information is
not available (for example, library and system routines), and steps into
any procedure for which debugging information is available.

Run runs the program. Control returns to the debugger when:


Ÿ The program ends, or
Ÿ The program stops at an enabled breakpoint.

When the debugger is running, the run button changes to

View changes the current program view window to one of the other
program view windows, depending on the views available for the
module. For example, you can change from the *LISTING view to
the *STATEMENT view.

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 209
Frequently Used Features of the Debugger

Call stack displays the Call Stack window, which allows you to view
all of the call stack entries. The procedures are displayed in the order
that they were called.

Monitor, from a program view window, displays the Monitor


Expression window. This button also appears on the left side of the
title bar on the Program Monitor window and the Local Variables
window.

Breakpoints displays the Breakpoints List window, which allows you


to view all the breakpoints that have been set.

Debug Session Control transfers control to the Debug Session


Control window.

Next Representation displays the next representation of the selected


variable.

Delete deletes the highlighted expression or variable.

Delete All deletes all expressions and variables.

Growth Direction changes the order of the entries on the call stack.

Running a Program
You can run your program by using step commands, the Run command, or the Run
to location command.
Step commands
Step commands control the running of the program. The running
of a line of code is reflected in all open views.
The step commands are located in the title bars and under the
Run menu-bar choice of the program view windows.

210 IBM VisualAge C++ for OS/400 C++ User’s Guide


Frequently Used Features of the Debugger

Run command
The Run command runs the program until a breakpoint is
encountered, the program is halted, or the program ends.
The Run command is located in the title bars and under the Run
menu-bar choice of the program view windows.
Run To Location command
The Run to location command runs the program to the current
position in the current program view window. To select a posi-
tion, press mouse button 1 once on the prefix area of a runnable
statement. The prefix area is the area on the left of the program
view window where the line numbers are displayed.
The Run to location command is located under the Run
menu-bar choice of the program view windows.

Setting Breakpoints
You can control how your program runs by setting breakpoints. A breakpoint stops
your program at a specific location.

To set breakpoints in one of the following ways:


Ÿ Select the Breakpoints menu from the Debug Session Control window or from
any of the program views windows
Ÿ Double-click in the prefix area of a runnable statement in any of the program
view windows
The prefix area turns red indicating that the breakpoint has been set. (The prefix
area color is configurable.)

See “Breakpoints Menu Choices” on page 219 for more information on break-
points.

Writing Code That the Debugger Supports


Using VisualAge C++, you can write your program code with stylistic features that
are not supported by the debugger:
Ÿ Multiple statements on the same line are difficult to debug.
Because individual statements cannot be accessed separately when you set break-
points or when you use step commands, you may want to avoid the use of mul-
tiple statements on the same line.
Ÿ Although it is possible to create programs that contain more than one module
with the same name (if the modules are in different libraries), the debugger does
not support them.

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 211
Frequently Used Features of the Debugger

Attempting to debug programs that contain two or more modules with the same
name will result in an error message being displayed.

Debugger Performance Considerations


To get optimal performance from the debugger, consider the following points:
Expression evaluations:
Ÿ Complex expressions take longer to evaluate than simple expressions.
Ÿ The settings of the Default Data Representation window affect the perform-
ance of expression evaluation:
– Representing character pointers, arrays, and character arrays as
hexadecimal pointers gives the best performance.
– Representing structures using System Defaults performs better than
using User Defaults.
– Representing a character array as a string is faster than representing it as
an array.
Ÿ Evaluating all of the elements of a large array takes longer than evaluating
single elements. Use the Monitor Expression window to evaluate a single
element.
Step performance:
Step performance is affected by the number of enabled monitor windows, the
numbers of expressions in the windows, and the complexity of the expression.
Step performance can be improved by:
Ÿ Disabling or deleting expressions that no longer need to be monitored.
Ÿ Displaying only single elements of an array.
Ÿ After following a chain of pointers to a variable, disabling the pointers used
and leaving only the variable active in the monitor.
Ÿ Not stepping with the Local Variables window enabled.
Ÿ Not stepping with the Call Stack window enabled. Minimizing the Call
Stack window will disable it.
Expanding the procedures within a module:
This function requires a lot of interaction with the AS/400. If a large number of
procedures are in a module, searching for the procedure name by using the Find
Procedure choice on the File menu is faster.
Using PC files instead of AS/400 source members:

212 IBM VisualAge C++ for OS/400 C++ User’s Guide


Frequently Used Features of the Debugger

For non-C++ programs, performance can be improved by copying the files to the
PC and using the Change text file choice from the View menu to specify the
path name of the PC file. This technique is especially useful when debugging
from remote sites.
Searching for a string in the text view:
String searches can be speeded up by the following:
Ÿ Keeping the source file on the workstation.
Ÿ Using the Find Procedure choice to search for procedures.
Ÿ Searching the *Listing view instead of a source view that is on the AS/400.
Using the From/To/Every entry fields on line breakpoints:
Large values specified for these options will significantly slow down your
program. If possible, an alternative is to set a conditional breakpoint by speci-
fying an expression.

Debugger Limits
The following limits apply when you debug applications with the VisualAge C++ for
OS/400 Debugger:
Limits:
Ÿ The largest string that can be displayed is 4080 characters.
Ÿ The largest number of bytes that can be displayed in a hexadecimal dump is
1024.
Ÿ The largest number of elements displayed in a COBOL array or an RPG
array is 500.
Ÿ The largest number of fields displayed in a COBOL record or an RPG struc-
ture is 500.
Ÿ Only 256 elements per dimension are returned for C and C++ arrays.
Ÿ Only 140 characters per line are displayed for the text views retrieved from
the AS/400. Files residing on the PC will have the entire line displayed
regardless of the line length.
Source files with a record size greater than 240:
Source physical files that have a record size greater than 240 characters cause a
message to be written to the job log for each record read. (The job log that the
messages are written to is the job log of the debug server job that is serving your
debug session.) This behavior slows down processing and may cause your debug
session to end if the job log grows too large.

Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 213
Frequently Used Features of the Debugger

214 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

14 Introducing the Primary Debugger Windows

This chapter introduces the primary debugger windows, and the menu items and
choices accessible from each of these windows. Topics include:
Ÿ Using the Debug Session Control window
Ÿ Using the Program View window

Using the Debug Session Control Window


The Debug Session Control window, shown below, is the control window of the
debugger.It is open during the entire debugging session. The window is divided in
two panes:
Ÿ The Threads pane contains the threads started by your program.
OS/400 programs always contain a single thread.
Ÿ The Application pane shows the program objects that are associated with the
application you are debugging.

Figure 34. Debug Session Control Window

From the Debug Session Control window you can perform the following tasks:
Display a list of modules contained within a program object
Select the plus icon to the left of the program object name
If the module you selected is composed of only one file, the procedures
contained within the module are listed; otherwise, a list of files is dis-
played

 Copyright IBM Corp. 1995 215


Using the Debug Session Control Window

Open a program view window of a module


Double-click on the module name
Open a program view window of a file
Double-click on the file name
Display a list of procedures for a specific module
Select the plus icon to the left of the module name or the file name
Open a program view window to a specific procedure
Double-click on the procedure name
Display the components of a program or a service program
Double-click on the program or service-program name displayed in the
Application pane
Display a component
Highlight the component name and press mouse button 2
Select View from the popup menu that displays.
Specify which components display in the Application list
Select Options → Window settings → Display style → Show all com-
ponents.
When this choice is enabled, all components are listed. Otherwise, only
components compiled and bound with debugging data are listed.

File Menu Choices


Select choices from the File menu of the Debug Session Control window to:
Ÿ Add a program to the list of programs to be debugged
Ÿ Remove a program from the list
Ÿ Open a new module
Ÿ Find a procedure
Ÿ Open a program view window that contains the next line to be run
Ÿ Start a new debugging session
Ÿ End a debugging session

Add Program...
Displays the Add Program window, which allows you to add a new program to the
list of programs being debugged.

216 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Figure 35. Add Program Window

To use the Add Program window:


1. Type the name of the program you want to add in the Program entry field.
The program name can be in any of the following formats:
Ÿ Library/program
Ÿ *LIBL/program
Ÿ *CURLIB/program
Ÿ Program (same as *LIBL/program)
2. Select the appropriate push button to continue.
Service program Check Box
Enable this check box if the program being added is a service program.

Remove program
Allows you to remove a program from the list of programs being debugged.

To remove a program:
1. Select the program you want to remove from the list.
2. Select the Remove program choice.

You cannot remove the program in which you are currently stopped or the startup
program.

Open new module


Displays the Open New Module window, which allows you to open a new module.
If you have multiple modules in your program, only one module is initially displayed.
Use the Open New Module window to open additional modules.

Chapter 14. Introducing the Primary Debugger Windows 217


Using the Debug Session Control Window

Figure 36. Open New Module Window

To use the Open New Module window, Type the name of the program object in the
Program entry field. Specifying the program name is an optional step. You have to
disable the All programs check box option to search only one program object.
All programs Check Box
Enable this option if you want to search all the program objects. Disable
this option if you want to search only one program object.
Debugging information only Check Box
Enable this option if you want to search only the modules that contain
debugging information.
Note: You can double-click on the name of a module, file, or procedure shown on
the Debugger Session Control window to open the module, file, or procedure.

Find procedure...
Displays the Find Procedure window, which allows you to open a program view
window to a particular procedure.

Figure 37. Find Procedure Window

218 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

To use the Find Procedure window:


1. Type the name of the procedure you want to find in the Procedure entry field.
2. Select the appropriate push button to accept the information you have entered and
to close the window.
Debugging information only Check Box
Enable this check box if you want to search only the modules that
contain debugging information.
Case sensitive Check Box
Enable this check box if you want to search for the string exactly as
typed. Disable this check box if you want to search for both uppercase
and lowercase characters.

If the procedure that you specified is not found, a message displays.

If more than one procedure that matches the name you specified is found, the proce-
dures are listed in the Procedure List window, where you can select the procedure
you want to view.

Where is execution point


Makes the program view window containing the next line to be run the active
window.

Startup...
Displays the Startup Information window, which allows you to start another debug-
ging session. Startup also allows you to stop debugging the current program and
debug another program.

Refer to “Starting the Debugger from an OS/2 Prompt” on page 205 for detailed
information.

Close debugger
Ends the debugging session. When you select the Close debugger choice, the Close
Debugger message box prompts you to confirm that you want to end the debugging
session.

Breakpoints Menu Choices


Select choices from the Breakpoints menu to:
Ÿ Set breakpoints to stop your program at any point
Ÿ List the breakpoints that are currently set
Ÿ Delete all the breakpoints in your program.
You can set as many breakpoints as you want.

Chapter 14. Introducing the Primary Debugger Windows 219


Using the Debug Session Control Window

Breakpoints can be set from:


Ÿ The Debug Session Control window
Ÿ The program view windows

When you set a breakpoint in one program view window, it is reflected in the other
program view windows.

Set line...
Displays the Line Breakpoint window, which allows you to set a line breakpoint to
stop your program at a specific line number.

Figure 38. Line Breakpoint Window

The Line Breakpoint window entry fields are as follows:


Ÿ Program
To select an item from the Program list:
1. Open the Program list by selecting the arrow with your mouse.
2. Highlight the program where you want to set the breakpoint, or type the
program name in the entry field.
Ÿ Module
To select an item from the Module list:
1. Open the Module list by selecting the arrow with your mouse.
2. Highlight the module where you want to set the breakpoint, or type the
module name in the entry field.

220 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Ÿ File
The File list contains names of files associated with the module you have
selected. At least one file is always associated with the selected module. More
than one file indicates this module contains source that was included as an
include file, and these include files contain runnable statements.
To select an item from the File list:
1. Open the File list by selecting the arrow with your mouse.
2. Highlight the file where you want to set the breakpoint, or type the name of
the file in the entry field.
Ÿ Line
To set a line breakpoint, type the line number in the Line entry field. The break-
point is set on the line number specified.
Ÿ Thread
OS/400 programs always contain a single thread.
Ÿ From
Type in a whole integer number to indicate how many times the breakpoint must
initially be satisfied before the program is stopped.
Note: A large value specified for this field may degrade the run-time perform-
ance of the application.
Ÿ To
Type in a whole integer number to indicate the total number of times the break-
point must be satisfied before it no longer stops the program. The value of this
field must be at least as large as the From field.
Ÿ Every
Type in a whole integer number to indicate how many times the breakpoint must
be satisfied within the From and To range before the program is stopped.
Note: A large value specified for this field may degrade the run-time perform-
ance of the application.
Ÿ Expression
When setting a breakpoint, you can also type in an expression. The program
stops only if this condition tests true. For example, you could type the following:
(i==1) || (j==k) && (k!=5)
The maximum length of the condition is 256 characters.
The syntax of the expression is language dependent. Refer to the appropriate doc-
umentation for the language you are using.

Chapter 14. Introducing the Primary Debugger Windows 221


Using the Debug Session Control Window

Select the appropriate push button to accept the information you have entered and
close the window.

List
Displays the Breakpoints List window, which lists all the breakpoints that have been
set.

Figure 39. Breakpoints List Window

For each breakpoint, the following information is provided:


Ÿ The program, module, and file
Ÿ The line number
Ÿ Whether it is enabled
Ÿ Its current state

For more information on the Breakpoints List window, refer to “Using the
Breakpoints List Window” on page 250.

Delete all
Deletes all the breakpoints that have been set. When you select the Delete all choice,
an information box displays for verification that you want to delete all the break-
points.

Monitors Menu Choices


Select choices from the Monitors menu of the Debug Session Control window to
display variables and expressions in a monitor, or to view the Call Stack or Local
Variables windows.

The first two choices listed under the Monitors menu are also accessible from
buttons in the title bars of the program view windows.

222 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Call stack
Displays the Call Stack window, which allows you to monitor the call stack.
This window is described in “Using the Call Stack Window” on page 243.

Local variables
Displays the Local Variables window, which allows you to display the local vari-
ables for the program&'s current procedure.

Run Menu Choices


Select choices from the Run menu to run your program, restart your program, or
minimize the debugger windows.

Run
Runs the program from the current line until a breakpoint is encountered or the
program ends. Input may be required from you to continue to the next breakpoint or
to end the program.

Restart
Allows you to restart the current debugging session on the existing program, while
Startup allows you to debug another program.

Hide debugger on Run


Minimizes the debugger windows while your application is running. The debugger
windows are temporarily not displayed. When the program stops, the windows are
displayed again.

Options Menu Choices


Select choices from the Options menu to control how the debugger windows are
shown.

Window settings→
Use the Window settings choice to modify how characteristics are displayed in the
Debug Session Control window.

Fonts...
Displays the system Font window. Any changes you make are reflected
in the Debug Session Control window. Select the appropriate push
button to continue.
Display style...
Displays the Display Style window.

Chapter 14. Introducing the Primary Debugger Windows 223


Using the Debug Session Control Window

Figure 40. Display Style Window

Use the Display Style window to modify the following characteristics:


Show all components Check Box
If enabled, all the components are displayed in the Debug
Session Control window. If not enabled, only the compo-
nents containing debugging information are displayed.
Show module path Check Box
If enabled, shows the path for the module.
Sort components Check Box
If enabled, components are sorted alphabetically in the Debug
Session Control window.
Sort threads Check Box
OS/400 programs always contain a single thread.
Show status line Check Box
If enabled, the status line is shown under the menu choices
on the Debug Session Control window.
Select the appropriate push button to continue.
Restore defaults
Restores the defaults of the window settings for the Debug Session
Control window. This includes the font, the style characteristics, and the
presentation of the title bar buttons.
Title bar buttons
If enabled, the title bar buttons are displayed on the title bar on the
Debug Session Control window.

224 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Debugger settings→
Use the Debugger settings cascading choice to set various debugger options that
control how the debugger windows are shown. These settings affect the behavior of
the debugger and remain in effect for the duration of the debugging session.

Debugger properties...
Displays the Debugger properties window where you can determine how your
modules are handled when they stop or are no longer active, and whether the
debugger displays the Busy notification box, steps with mouse button 2, or allows
multiple views of the same module to be displayed concurrently.

Figure 41. Debugger Properties Window

Display at stop Group Heading

OS/400 programs always contain a single thread. The Only stopping thread radio
button should always be enabled for OS/400 programs. The All threads radio button
is not valid for OS/400 programs.

Busy notification Group Heading

Chapter 14. Introducing the Primary Debugger Windows 225


Using the Debug Session Control Window

When the debugger is busy, you can choose to have a notification box displayed.
You also can specify, by selecting one of the location radio buttons, where you want
the notification box to be displayed.
Display notification Check Box
Enable this check box to display the debugger busy box when the
debugger is busy. Disable this check box to prevent the box from
showing.
Center Radio Button
The debugger busy box is shown in the center of your display.
Top Left Radio Button
The debugger busy box is shown in the top, left-hand corner of
your display.
Top Right Radio Button
The debugger busy box is shown in the top, right-hand corner of
your display.
Bottom Left Radio Button
The debugger busy box is shown in the bottom, left-hand corner of
your display.
Bottom Right Radio Button
The debugger busy box is shown in the bottom, right-hand corner
of your display.

Old module disposition Group Heading

In the course of debugging, these selections allow you to control the behavior of
program view windows from which control has just passed. The Old module dispo-
sition controls the behavior of program view windows.

The dispositions that the views can take are:


Keep Radio Button
Leaves open the program view windows that do not contain the
modules that you select with Display at stop.
Iconize Radio Button
Changes into icons the views that do not contain the modules that
you select with Display at stop.
Discard Radio Button
Disposes of the views that do not contain the modules that you
select with Display at stop.

Settings Group Heading

226 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Step with mouse button 2 Check Box


You can choose to use mouse button 2 to step over. If you do not
use mouse button 2 to step over, clicking on mouse button 2 when
the mouse is pointing to a variable, an expression, or an object,
displays a popup menu.
Multiple views Check Box
You can choose to display more than one program view window
for a particular module. If this check box is enabled, when you
open a new view of a module, the first view stays open and is
overlaid by the second view. If this check box is disabled, the first
view is closed when a second view is opened. The default is not to
display multiple program view windows.

Select the appropriate push button to continue.

Monitor properties...
Displays the Monitor Properties window, which allows you to select the settings for
monitoring variables or expressions.

Figure 42. Monitor Properties Window

Use the Monitor Properties window to set the following:


Ÿ The window into which the variable or expression being monitored is placed.
Ÿ For popup expression windows, how long the monitor windows display.

Monitor Location Group Heading

Choose one of the following radio buttons to select the monitor window that opens
when you select a variable or an expression to monitor. The selections that you can
make, and the corresponding windows, are:
Popup monitor Display the variable or expression in a popup monitor window.

Chapter 14. Introducing the Primary Debugger Windows 227


Using the Debug Session Control Window

Private monitor Display the variable or expression in the Private Monitor


window.
Program monitor Display the variable or expression in the Program Monitor
window.

Popup Duration Group Heading

If you select Popup monitor from the Monitor location group heading, select one of
the following radio buttons to specify how long the popup monitor window is shown:
Step/run The monitor window closes when the next step command or Run
command is run.
New module The monitor window closes when the program stops in a new
module.
Permanent The monitor window stays open until the end of the debugging
session.

Default data representation →


Use the choices from Default data representation to change the representation for a
data type in a specific language.

When you select a choice, the Default Representation window is shown.


C and C++
Use the C and C++ choice to change the default representation of the selected data
type. For example, you can change the default representation for an integer in the
C language from decimal to hexadecimal.
You can change the representation of the value displayed in a monitor to:
Ÿ Array
Ÿ Character
Ÿ Decimal
Ÿ Floating-point
Ÿ Hexadecimal
Ÿ Hexadecimal pointer
Ÿ String
Ÿ System defaults
Ÿ User defaults
Note: The representation you can select varies with the data type being displayed.
When the System Defaults radio button is selected, the data type is for-
matted using the AS/400 default format for that data type. When the User
Defaults radio button is selected, the format specified by the user for that
data type is used.

228 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Select the appropriate radio button for the data type you want.
Select the appropriate push button to continue.

Figure 43. Default Data Representation - C and C++ Window

System
Use the System choice to change the default representation for the VisualAge C++
for OS/400 debugger. Use this choice for languages other than C and C++.
Use the Default Representation - System window to select how you want your
data represented in the monitor windows. The Default Representation - System
window is for all languages other than C and C++.
You can change the representation of the value displayed in a monitor to either
hexadecimal or the system default. The system default uses the defaults established
by the AS/400 system.
Select the appropriate radio button for the data type you want.
Select the appropriate push button to continue.

Chapter 14. Introducing the Primary Debugger Windows 229


Using the Debug Session Control Window

Figure 44. Default Data Representation - System Window

Program profiles→
Use the Program profiles cascading choice to specify where you want the debugger
profile and session settings placed or to delete program profile information.

Program profiles are used to restore the debugger windows and breakpoints when
debugging a program more than once. They are stored separately for each program
debugged. The file extension for the files that contain this information is @8R.
Note: Only information for the startup program is restored.

The debugger program profile information file contains your selections for most of
the debugger settings and information. You choose whether to save your selections
for the next debugging session by selecting Save settings in an option window.
Select information
Select the Select information choice to choose the items for which profile infor-
mation should be saved in the program profile.

230 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Debug Session Control Window

Figure 45. Select Information Window

Delete program profile


Select the Delete program profile choice to delete the profile information for a
program that you have previously debugged.
Change location
Select the Change location choice to specify where to store the program profile
information.
The location of the directory where the profile information is stored should be on
an HPFS file system. If the directory is stored on a FAT file system, the debugger
will not be able to distinguish profile information for OS/400 programs whose
names have the same first 8 characters.

Figure 46. Change Location Window

Chapter 14. Introducing the Primary Debugger Windows 231


Using the Program View Window

Save debugger window positions


When you select this choice, the window positions and sizes are saved for the debug-
ging session. You do not need to save program profile information for this choice to
take effect.

Global font change


When you select this choice, the system Font window is shown. Any changes you
make are reflected in all of the debugger windows.

Enable window cascading


When you select this choice, successive windows that are opened are allowed to
overlap each other on the display. If you disable this choice, successive windows
cover previously displayed windows.

Windows Menu Choices


Select the Windows menu of the Debug Session Control window to view a list of
all the open debugger windows. If you select a window from the list, it becomes the
active window.

Help Menu Choices


Select choices from the Help menu of the Debug Session Control window to display
the various types of help information.

Help index Displays an alphabetical index of all available


debugger help topics.
General help Displays help information for the active window.
Using help Describes how to use the IBM VisualAge C++ for
OS/400 Debugger help facility.
How do I Displays the debugger task help.
Product information Displays product information.

Using the Program View Window


A program view window allows you to view the program you are debugging. You
can look at your application in one of the following views:
Ÿ *TEXT
Ÿ *LISTING
Ÿ *STATEMENT.

The *TEXT view displays the source code for the module that contains the main
procedure of the program being debugged. If it is available, the *TEXT view is

232 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Program View Window

shown with the Debug Session Control window when the debugging session starts.
If the *TEXT view is not available, the *LISTING view is shown if it is available.
If neither the *TEXT view nor the *LISTING view is available, the *STATEMENT
view is shown.

Figure 47. *TEXT View Window

The *LISTING view displays the compiler generated listing of your program. Each
runnable statement is assigned a statement number. The *LISTING view menu
choices are the same as in the *TEXT view.

The *STATEMENT view displays the procedure name of each statement. Each line
shows the line number, the statement ID, and the procedure name. The *STATE-
MENT view menu choices are the same as in the *TEXT view.

Runnable lines in a program view window initially display in blue and non-runnable
lines initially display in black. These colors are configurable.

Any highlighted lines or breakpoints in the existing program view window are also
shown in any new program view window that you open.

Chapter 14. Introducing the Primary Debugger Windows 233


Using the Program View Window

File Menu Choices


Select choices from the File menu of a program view window to open a new source
file, find a procedure, find the next line to be run, start a new debugging session, or
end a debugging session.

Open new module...


Displays the Open New Module window, which allows you to open a new module.
Refer to “Open new module” on page 217 for detailed information.

Find procedure...
Displays the Find Procedure window, which allows you to open a program view
window to a particular procedure. Refer to “Find procedure...” on page 218 for
detailed information.

Where is execution point


Makes the program view window containing the next line to be run the active
window.

Startup...
Displays the Startup Information window, which allows you to start another debug-
ging session. Startup also allows you to stop debugging the current program and
debug another program.

Refer to “Starting the Debugger from an OS/2 Prompt” on page 205 for detailed
information.

Close debugger
Ends the debugging session. When you select the Close debugger choice, the Close
Debugger message box prompts you to confirm that you want to end the debugging
session.

View Menu Choices


Select choices from the View menu to search for strings in the text, select a different
view of your program, change to a different source file, view include files, or have
the view move to a specific line number.

.
Displays the Find window. The Find window allows you to search for a text string
in the active program view, starting at the current cursor position. You can search for
simple text strings. Wildcard expressions are interpreted as simple text strings by the
search function.

234 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Program View Window

Figure 48. Find Window

To use the Find window to find a text string:


1. Type the text string that you want to find in the Text entry field.
2. Select the OK push button.

The search string can have:


Ÿ Alphabetic and numeric characters
Ÿ A maximum of 256 characters
Ÿ Uppercase and lowercase characters.
Case sensitive Check Box
Enable this check box if you want to search for the string exactly as
typed. Disable this check box to search for uppercase and lowercase
characters.

Find next
Allows you to search for the next occurrence of the text string that you typed in the
Find window. If you are searching in the same module, the default is the text string
you typed in the last time you used the Find window for this module.

Scroll to line number...


Displays the Scroll to Line Number window, which allows you to go to a particular
line in your program.

Figure 49. Scroll to Line Number Window

Chapter 14. Introducing the Primary Debugger Windows 235


Using the Program View Window

To use the Scroll to Line Number window to scroll to a specific line:


1. Type the line number to which you want to scroll in the Line entry field.
2. Select the OK push button to scroll to that line.

Select include...
Displays the Select Include window, which allows you to view the files that are
included in your program.

Figure 50. Select Include Window

To use the Select Include window:


1. Select the include file. The include file name is highlighted.
2. Select the OK push button. The include file you selected is shown.

Change text file...


Displays the Change Text File window, which allows you to specify a file name to
be used as the source in the current view.

You can replace the path name or file name of the program you are debugging with a
new path name or file name.

This is useful if the debugger found the incorrect source file for your program, so that
you can specify the use of a different source file from a different directory.

236 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Program View Window

Changing the text file can improve the performance of the debugger over slower com-
munications lines. By copying source files, listing files, or both to the workstation,
the time required to access the source can be reduced.

Figure 51. Change Text File Window

To replace the file name:


1. Type the new path name or file name in the File entry field or select the File list
push button to see a list of file names.
2. Select the OK push button.

To restore a view to the AS/400 view:


1. Type an asterisk (*) in the File entry field.
2. Select the OK push button.

*TEXT
Displays the *TEXT view.

*LISTING
Displays the *LISTING view.

*STATEMENT
Displays the *STATEMENT view.

Breakpoints Menu Choices


Select choices from the Breakpoints menu to set breakpoints to stop your program at
any point, list the breakpoints that are currently set, or delete all the breakpoints.
You can set as many breakpoints as you want.

Breakpoints can be set from the program view windows or from the Debug Session
Control window. When you set a breakpoint in one program view window, it is
reflected in the other views.

Chapter 14. Introducing the Primary Debugger Windows 237


Using the Program View Window

Set line...
Displays the Line Breakpoint window, which allows you to set a line breakpoint to
stop your program at a specific line number. Refer to “Set line...” on page 220 for
a description of the Line Breakpoint window.

List
Displays the Breakpoints List window, which lists all the breakpoints that have been
set.

The following information is provided for each breakpoint.


Ÿ The enablement state
Ÿ The position of the breakpoint
Ÿ The conditions under which the breakpoint is activated.

For more information on the Breakpoint List window, refer to “Using the Break-
points List Window” on page 250.

Toggle at current line


Sets a breakpoint on the current line if one does not exist, or removes an existing
breakpoint on the current line.

Delete all
Deletes all the breakpoints that have been set.

Monitors Menu Choices


Select choices from the Monitors menu of the program view windows to monitor
expressions or variables, to display the Call Stack window, or to display the Local
Variables window.

Monitor expression...
Displays the Monitor Expression window as shown in Figure 52 on page 239,
which allows you to monitor expressions or variables and to add them to various
monitor windows.

238 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Program View Window

Figure 52. Monitor Expression Window

Use the Monitor Expression window to type in the name of an expression you want
to monitor. This window lists the following contextual information:
Ÿ The module you are in.
Ÿ The active line of the source code, which is highlighted.
Ÿ The view of the program that is active.
Ÿ The thread you are in.

To specify an expression to be monitored:


1. Type the name of the variable or expression you want to monitor in the
Expression entry field.
2. Select the appropriate radio button for the location where you want to monitor
your expression.
3. Select the appropriate push button to accept the information you have entered and
close the window.
Note: The expression displays as specified in the Monitor Properties window.
To change the default location, select Options → Debugger settings → Monitor
properties from the program view windows or the Debug Session Control
window.

Call stack
Displays the Call Stack window, which allows you to monitor information about all
programs and procedures in the call stack. This window is described in “Using
the Call Stack Window” on page 243.

Local variables

Chapter 14. Introducing the Primary Debugger Windows 239


Using the Program View Window

Displays the Local Variables window, which allows you to display the local vari-
ables for the current function of the program. This window is described in
“Using the Local Variables Window” on page 246.

Run Menu Choices


Select choices from the Run menu to run your program, run your program to a spe-
cific location, step through your program, or minimize debugger windows.

You can access any of the choices in the Run menu by using the shortcut keys.
These keys are also listed in the Run menu. For the Step over command, you can
use mouse button 2 if it is enabled on the Debugger Properties window.

When you select a choice from the Run menu, the status line indicates that the appli-
cation is running, and you should be aware that the application might require input to
continue.

Step over
Runs the current line in the program, but does not enter any called procedure. If the
current line is a call, the program stops when the call completes.

Step debug
Runs the current line in the program. The debugger steps over any procedure for
which debugging information is not available (for example, library and system rou-
tines), and steps into any procedure for which debugging information is available.

Run
Runs the program. Control returns to the debugger when the program ends or the
program stops at an enabled breakpoint.

Restart
Select the Restart choice to start the debugging session again. Restart allows you to
restart the current debugging session on the existing program, while Startup allows
you to debug another program.

Run to location
Runs your program from the current line up to the line that is highlighted in the
prefix area.

To use the Run to location choice:


1. Single-click in the prefix area of the line that you want to become the current
line. The prefix area will be highlighted.
2. Select the Run to location choice. The program runs up to the line that you
marked.

240 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Program View Window

The Run to location choice stops only on runnable lines. If a highlighted line is not
runnable, the run is not performed.

Hide Debugger on Run


Minimizes the debugger windows while your application is running. The debugger
windows are temporarily not displayed. When the program stops, the windows are
displayed again.

Options Menu Choices


Select choices from the Options menu to control how the debugger windows display.

Window settings→
Use the Window settings cascaded choices to modify the colors and the font of the
program view and the presentation of the notebook view and title bar buttons.

Colors...

Displays the Module Window Colors window, which allows you to change the color
of the lines in the program view windows.

To change the colors of the lines in a module window:


Ÿ Open the OS/2 Color Palette window.
Ÿ Select a color from the color palette.
Ÿ Hold down mouse button 2 and drag the selected color to the line that you want
to change in the Module Window Colors window.
Ÿ Release mouse button 2.
Ÿ Select the appropriate push button to accept the information you have entered and
close the window.

Fonts...

Displays the Font window. Use the Font window to change the font of the text in
the program view windows. Any changes you make are reflected in the program
view windows. Select the appropriate push button to continue.

Restore defaults

Restores the defaults for the colors and fonts of the program view windows and the
presentation of the notebook view and the title bar buttons.

Notebook

Chapter 14. Introducing the Primary Debugger Windows 241


Using the Program View Window

Enable the Notebook choice to display the program view windows in notebook
format. If you have include files in your program, the Notebook choice is enabled
by default.

You can enable or disable the Notebook choice by selecting it. When the Notebook
choice is enabled, a check mark is displayed next to the choice.

The *TEXT view can be displayed in notebook format if at least one include file
with runnable statements is included. The *LISTING and *STATEMENT views
cannot be displayed in notebook format.

Title bar buttons

If enabled, the title bar buttons are displayed on the title bar on the program view
windows.

Debugger settings→
Use the Debugger settings cascaded choices to set various debugger options that
control how the debugger windows display. These settings affect the behavior of the
debugger and remain in effect for the duration of the debugging session.

Refer to “Debugger settings→” on page 225 for a description of the choices.

Windows Menu Choices


Select the Windows menu of the program view windows to view a list of all the
open debugger windows. If you select a window from the list, it becomes the active
window.

Help Menu Choices


Select choices from the Help menu of the program view windows to display the
various types of help information.

Help index Displays an alphabetical index of all available debugger


help topics.
General help Displays help information for the active window.
Using help Describes how to use the IBM VisualAge C++ for OS/400
Debugger help facility.
How do I Displays the debugger task help.
Product information Displays product information.

242 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Call Stack Window

15 Introducing the Secondary Debugger Windows

This chapter introduces additional debugger windows, including:


Ÿ Call stack window
Ÿ Local variables window
Ÿ Monitor window
Ÿ Breakpoints list window

Using the Call Stack Window


The Call Stack window shown below displays information about all programs and
procedures in the call stack. The programs and procedures are displayed in the order
that they were called.

Figure 53. Call Stack Window

When the state of the job changes, such as when you run the program, the Call Stack
window changes to reflect the current state. You can double-click on any debuggable
ILE entry in the Call Stack window to display a program view window for that
entry. The line that calls the next stack entry is highlighted. If you double-click on
the most recent call stack entry, the line where you are currently stopped is displayed.
Double-clicking on entries in the Call Stack window that are not debuggable, such as
original program model (OPM) entries or ILE entries compiled without debug data,
will result in an error message being displayed.

To display the Call Stack window, select Call Stack from the Monitors menu or

select the Call Stack button in the title bar.

 Copyright IBM Corp. 1995 243


Using the Call Stack Window

File Menu Choice


Use the Close debugger choice from the File menu to end the debugging session.

Close debugger
Use the Close debugger choice to end the current debugging session. When you
select the Close debugger choice, the Close Debugger message box prompts you to
confirm that you want to end the debugging session.

Options Menu Choices


Use choices from the Options menu to control how the items on the call stack
display and to set various debugger options.

Fonts...
Displays the Font window, which allows you to select the type of font you want to
use for the Call Stack window. Any changes you make are reflected in the program
view windows. Select the appropriate push button to continue.

Display style...
Displays the Display style window, which allows you to select the type of informa-
tion you want displayed for the call stack entries, and you can choose if you want
new call entries displayed from top to bottom or bottom to top.

Figure 54. Display Style Window

To use the Display Style window:


1. Select one or more of the items under Columns to select the information you
want to display for each call stack entry. Each item causes a new column to be
added to the Call Stack window.

244 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Call Stack Window

The following items are available:


Call Level Represents the position of the call stack entry in the
list. The larger the number, the more recent the entry
is.
Library Lists the name of the library that contains the program.
Program Lists the program name that contains the procedure.
Module Lists the name of the module that contains the proce-
dure.
Procedure Lists the name of the procedure.
Statement Lists the statement identifier that indicates the exe-
cution point in the corresponding procedure or
program. For all entries except the most recent (the
one with the largest call level), the statement ID
represents the last statement run. For the most recent
entry, the next statement to be run is represented.
A blank statement ID is displayed if the procedure
does not contain any statements.
Statements correspond to statement IDs in the
*LISTING view or *STATEMENT view. These are
not line numbers of any view.
Program Type Lists the type of program. The types are as follows:
OPM Original program model program
ILE Integrated Language Environment
program
SRVPGM Integrated Language Environment
service program
Call Level Number Lists the number assigned to the call level. Every
time a procedure or OPM program is called, a unique
and higher number is assigned to the call level.
2. Select one of the following Growth direction radio buttons to determine how
new items are displayed on the call stack.
Up Displays new items at the top of the Call Stack window.
Down Displays new items at the bottom of the Call Stack window.
3. Select the appropriate push button to accept the information you have entered and
close the window.

Chapter 15. Introducing the Secondary Debugger Windows 245


Using the Local Variables Window

Restore Defaults
Restores all of the Call Stack window settings to their original settings. This
includes the font, the style settings, and the presentation of title bar buttons.

Title bar buttons


If enabled, the title bar buttons are displayed on the title bar on the Call Stack
window.

Windows Menu Choices


Select the Windows menu of the Call Stack window to view a list of all the open
debugger windows. If you select a window from the list, it becomes the active
window.

Help Menu Choices


Select choices from the Help menu of the Call Stack window to display the various
types of help information.

Help index Displays an alphabetical index of all available debugger


help topics.
General help Displays help information for the active window.
Using help Describes how to use the IBM VisualAge C++ for OS/400
Debugger help facility.
How do I Displays the debugger task help.
Product information Displays product information.

Using the Local Variables Window


The Local Variables window, as shown in Figure 55 on page 247, monitors the
local variables (static and automatic) for the current run point in the program. The
contents of the Local Variables window change each time your program enters or
leaves a procedure. The contents can also change each time a step or run operation
occurs.

246 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Local Variables Window

Figure 55. Local Variables Window

Expression requirements are language dependent when changing the value of vari-
ables. See the appropriate user guide for the language you are using.
Note: When your program returns from a called procedure, the data display options
you previously selected (for example, representation) are lost. If you want to save
these display options, monitor the variable or expression in a Private Monitor
window, the Program Monitor window, or a popup expression window.

File Menu Choices


Use the choice from the File menu to end the debugging session.

Close Debugger
Use the Close debugger choice to end the current debugging session. When you
select Close debugger choice, the Close Debugger message box prompts you to
confirm that you want to end the debugging session.

Edit Menu Choices


Select the choices from the Edit menu of the Local Variables window to delete,
select, or de-select variables.

Chapter 15. Introducing the Secondary Debugger Windows 247


Using the Local Variables Window

Delete
Select the Delete choice to delete variables or expressions that are being monitored
from a monitor window.

To delete a variable or expression from a monitor window:


1. Select the variable or expression with your mouse. The monitor for the variable
or expression is highlighted.
2. Select the Delete choice from the Options menu.

Select All
Select the Select all choice to select all the expressions in the window. Select
expressions can be controlled by using the Options menu. For example, by selecting
one or more expressions, you can change the representation for all the selected
expressions at one time.

Deselect All
Select the Deselect all choice to cancel the selection of all the expressions in the
window.

Other Elements...
Select the Other elements choice to choose which elements of an array are shown.
Initially, only the first 50 elements of the array are displayed. After that, you can
select the range of array elements that you want displayed. Fifty elements are shown
at a time.

Representation→
Select the Representation cascading choice to display the contents of the variable in
a new representation. The types of representation that display on the menu depend on
the data type of the variable you are monitoring.

The following are possible representations:


Ÿ Array
Ÿ Character
Ÿ Decimal
Ÿ Floating-point
Ÿ Hexadecimal
Ÿ Hexadecimal pointer
Ÿ String

Options Menu Choices


Select choices from the Options menu to control how the contents of variables
display and to set the debugger options.

248 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Local Variables Window

Fonts...
Displays the Font window, which allows you to select the type of font you want to
use for the Local Variables window. Any changes you make are reflected in the
Local Variables window. Select the appropriate push button to continue.

Restore Defaults
Restores the defaults for all the items in this menu.

Show Enablement
Select the Show enablement choice to display the enablement status of a variable or
expression. If a variable or expression is enabled, the displayed contents are updated
as they change.

If you disable this choice, the enablement status is not shown.

Show Context
Select the Show context choice to display the contextual information for the variable
you are monitoring. The following information displays:
Ÿ Source
Ÿ File
Ÿ Line
Ÿ Thread

If you disable this choice, the contextual information is not shown.

Title Bar Buttons


If enabled, the title bar buttons are displayed on the title bar on the Local Variables
window.

Windows Menu Choices


Select the Windows menu from the Local Variables window to view a list of all the
open debugger windows. If you select a window from the list, it becomes the active
window.

Help Menu Choices


Select choices from the Help menu of the Local Variables window to display the
various types of help information.

Help index Displays an alphabetical index of all available debugger


help topics.
General help Displays help information for the active window.

Chapter 15. Introducing the Secondary Debugger Windows 249


Using the Breakpoints List Window

Using help Describes how to use the IBM VisualAge C++ for OS/400
Debugger help facility.
How do I Displays the debugger task help.
Product information Displays product information.

Using the Monitor Windows


The debugger has three other windows that allow you to monitor variables and
expressions:
Ÿ The Popup expression window
Ÿ The Program monitor window
Ÿ The Private monitor window

A Popup Expression window monitors single variables or expressions. This window


is associated with a specific program view window. The duration that the Popup
Expression window is open can be customized on the Monitor Properties window.

The variables or expressions can be transferred either to the Program Monitor


window or to the Private Monitor window.

The Program Monitor and the Private Monitor windows are used as collectors for
individual variables or expressions you might be interested in. Variables and
expressions may be created in these monitors or may be transferred to them from a
Popup Expression window.

The difference between the Private Monitor window and the Program Monitor
window is the length of time that they remain open. The Program Monitor window
remains open for the entire debugging session. The Private Monitor window is
associated with the program view window from which it was opened, and closes
when its associated view is closed.

For all the monitor windows, expression requirements are language dependent. See
the appropriate user guide for the language you are using.

Using the Breakpoints List Window


Use the Breakpoints List window to display a list of the breakpoints that have been
set. The following information is provided for each breakpoint that has been set:
Ÿ Program
Ÿ File
Ÿ Line
Ÿ State

250 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Breakpoints List Window

Ÿ Status

Additional breakpoint information, such as the conditions under which the breakpoint
is activated, can be displayed using the Options menu of the Breakpoints List
window.

To display the Breakpoints List window, select List from the Breakpoints menu of
the Debug Session Control window or a program view window, or select the Break-

points button in the title bar.

Figure 56. Breakpoints List Window

File Menu Choices


Select the choice from the File menu of the Breakpoints List window to end a
debugging session.

Close Debugger
Use the Close debugger choice to end the current debugging session. When you
select Close debugger choice, the Close Debugger message box prompts you to
confirm that you want to end the debugging session.

Edit Menu Choices


Select the choices from the Edit menu of the Breakpoints List window to delete,
disable or enable, modify, or delete all breakpoints.

Delete
Deletes the highlighted breakpoints in the window.

To delete a breakpoint:

Chapter 15. Introducing the Secondary Debugger Windows 251


Using the Breakpoints List Window

1. Highlight the breakpoint you want to delete.


2. Select the Delete choice.

Disable/Enable
Disables the highlighted breakpoint if it is enabled, or enables the highlighted break-
point if it is disabled.

To disable or enable a breakpoint:


1. Highlight the breakpoint you want to disable or enable.
2. Select the Disable/Enable choice.
Note: Enabling a breakpoint does not cause the debugger to reset its internal
counters associated with the From, Every, and To fields.

Modify
Use the Modify choice to change the breakpoints that have been set in your program.

To modify a breakpoint:
1. Highlight the breakpoint you want to change.
2. Select the Modify choice. The Line Breakpoint window is shown.
3. The entry fields contain the information pertaining to that breakpoint. Make your
changes to the entry fields.
4. Select OK to accept the changes and close the window. If you want to make
other changes, select Set to accept the changes and keep the window open.
Note: Modifying a breakpoint does cause the debugger to reset its internal counters
associated with the From, Every, and To fields of the breakpoint.

Delete All
Deletes all the breakpoints that have been set in your program.

To delete all the breakpoints:


1. Select the Delete all choice. The Delete All Breakpoints window displays.
2. Select Yes from the Delete All Breakpoints window.

Disable All
Select this choice to disable all breakpoints that are currently set in your program.

Enable All
Select this choice to enable all breakpoints that are currently set in your program.
Note: Enabling a breakpoint does not cause the debugger to reset its internal
counters associated with the From, Every, and To fields.

252 IBM VisualAge C++ for OS/400 C++ User’s Guide


Using the Breakpoints List Window

Set Menu Choices


Select the Set line... choice from the Set menu of the Breakpoints List window to
set a line breakpoint. Refer to “Breakpoints Menu Choices” on page 219 for a
description of the Set menu choice.

Options Menu Choices


Select choices from the Options menu of the Breakpoints List window to sort the
breakpoints, change the style, change the font, and show or hide title bar buttons for
the window.

Fonts...
Displays the Font window, which allows you to select the font you want to use for
the text in the Breakpoints List window. Any changes you make are reflected in the
Breakpoints List window. Select the appropriate push button to continue.

Display Style...
Displays the Display Style window, which allows you to control how the items in the
breakpoints list are shown.

Figure 57. Display Style Window

To change how the items in the breakpoints list are shown:


Ÿ Select one or more of the items under the Columns group heading. Each item
you select causes a new column to be added to the Breakpoints List window.
Ÿ Select the appropriate push button to continue.

Sort...
Displays the Sort Breakpoints window, which allows you to sort the breakpoints by
the characteristics of the breakpoint.

Chapter 15. Introducing the Secondary Debugger Windows 253


Using the Breakpoints List Window

Breakpoints can be sorted according to the following categories:


Ÿ Program
Ÿ Module
Ÿ File
Ÿ Line
Ÿ State
Ÿ Status
Ÿ Expression
Ÿ From
Ÿ To
Ÿ Every

Select the category by which you want to sort and select the appropriate push button
to continue.

Restore Defaults
Restores the defaults for all the items in this menu.

Title Bar Buttons


Shows the title bar buttons on the Breakpoints List window title bar if they are cur-
rently hidden, or hides them if they are currently shown.

Windows Menu Choices


Select the Windows menu from the Breakpoints List window to view a list of all
the open debugger windows. If you select a window from the list, it becomes the
active window.

Help Menu Choices


Select choices from the Help menu of the Breakpoints List window to display the
various types of help information.

Help index Displays an alphabetical index of all available debugger


help topics.
General help Displays help information for the active window.
Using help Describes how to use the IBM VisualAge C++ for OS/400
Debugger help facility.
How do I Displays the debugger task help.
Product information Displays product information.

254 IBM VisualAge C++ for OS/400 C++ User’s Guide


16 Using the ILE Source-Level Debugger

The previous chapters have introduced you to debugging AS/400 applications from
your OS/2 workstation using the VisualAge C++ for OS/400Debugger

This chapter introduces the ILE source-level debugger you can use to debug AS/400
applications from the AS/400. Topics cover:
Ÿ Introducing the source-level debugger
Ÿ Preparing a program for debugging
Ÿ Starting the ILE source-level debugger
Ÿ Adding and removing programs from a debug session
Ÿ Viewing the program source
Ÿ Setting and removing breakpoints
Ÿ Stepping through a program
Ÿ Displaying the value of variables and expressions
Ÿ Changing the value of scalar variables
Ÿ Equating a name with a variable, expression, or debug command

Sample programs illustrate the following concepts:


Ÿ Using EVAL commands
Ÿ Displaying system and space pointers
Ÿ Displaying C++ constructs

See the chapter on debugging in ILE Concepts for more information on the ILE
source-level debugger, including authority required to debug a program or service
program and the effects of optimization levels.

Attention: While debugging and testing your programs, ensure that your library list is
changed to direct the programs to a test library containing test data so that any
existing real data is not affected.

You can prevent database files in production libraries from being modified uninten-
tionally, by using one of the following commands:
Ÿ Use the Start Debug (STRDBG) command and retain the default *NO for the
UPDPROD parameter
Ÿ Use the Change Debug (CHGDBG) command
Ÿ Use the Set Debug (SETDBG) command

 Copyright IBM Corp. 1995 255


Introducing the ILE Source-Level Debugger

See the appendix on debugging in CL Reference for more information on pre-


venting unintended modification of production files.

Introducing the ILE Source-Level Debugger


The ILE source-level debugger is used to detect errors in and eliminate errors from
programs and service programs. Using debug commands with any ILE program, you
can:
Ÿ View the program source or change the debug view
Ÿ Set and remove conditional and unconditional breakpoints
Ÿ Step through a specified number of statements
Ÿ Display the value of variables, expressions, structures, unions, records, arrays,
pointers, bit fields, enumerations, and classes
Ÿ Change the value of variables
Ÿ Equate a shorthand name with a variable, expression, or debug command

Before you can use the ILE source-level debugger, you must compile your source
with one of the debug options /Ti+, /Til, /Tin, or /Tis on the iccas compiler
invocation command.

After starting the source-level debugger, you can set breakpoints and call the
program. When the program stops because of a breakpoint or a step command, the
pertinent module's view is shown on the display at the point where the program
stopped. At this point, you can perform other actions such as displaying or changing
the value of variables.
Note: If your program has been optimized, you can still display variables, but their
values may not be reliable. To ensure that the content of variables or data structures
contain their correct (current) values, specify the /O- option with the iccas
command when compiling your source file, to set the optimization level to none.

Debug Commands for the ILE Source-Level Debugger


Debug commands and their parameters are entered on the debug command line dis-
played on the bottom of the Display Module Source and Evaluate Expression dis-
plays. They can be entered in uppercase, lowercase, or mixed case.
Note: The debug commands entered on the debug command line are not CL com-
mands.
Command Description
ATTR Permits you to display the attributes of a variable. The attributes are
the size and type of the variable as recorded in the debug symbol table.

256 IBM VisualAge C++ for OS/400 C++ User’s Guide


Introducing the ILE Source-Level Debugger

BREAK Permits you to enter either an unconditional or conditional breakpoint


at a position in the program being tested. Use BREAK line-number
WHEN expression to enter a conditional breakpoint.
CLEAR Permits you to remove conditional and unconditional breakpoints.
DISPLAY Allows you to display the names and definitions assigned by using the
EQUATE command. It also allows you to display a different source
module than the one currently shown on the Display Module Source
display. The module must exist in the current program.
EQUATE Allows you to assign an expression, variable, or debug command to a
name for shorthand use.
EVAL Allows you to display or change the value of a variable or to display
the value of expressions, records, structures, classes, arrays, pointers,
bit fields, or enumerations.
QUAL Allows you to define the scope of variables that appear in subsequent
EVAL commands.
SET Allows you to change debug options.
STEP Allows you to run one or more statements of the program being
debugged.
FIND Searches for a specified string of text on the Display Module Source
or Evaluate Expression display. A specified line number can also be
found on the Display Module display.
UP Moves the displayed window of source towards the beginning of the
view by the amount entered.
DOWN Moves the displayed window of source towards the end of the view by
the amount entered.
LEFT Moves the displayed window of source to the left.
RIGHT Moves the displayed window of source to the right by the number of
characters entered.
TOP Positions the view to show the first line.
BOTTOM Positions the view to show the last line.
NEXT Positions the view to the next breakpoint in the source currently dis-
played.
PREVIOUS Positions the view to the previous breakpoint in the source currently
displayed.
HELP Shows the online help information for the available source-level
debugger commands.

Chapter 16. Using the ILE Source-Level Debugger 257


Preparing a Program for Debugging

The online help for the ILE source-level debugger describes the debug commands,
explains their allowed abbreviations, and provides syntax diagrams for each
command. It also provides examples in each of the ILE languages of displaying and
changing variables using the source-level debugger. You can access Help while in a
debug session by pressing F1 (Help).

Debug Limits
The following is a list of debug limits for the ILE Source-Level Debugger:
Ÿ Function calls cannot be used in debug expressions. This is a limitation of the
debug expression grammar.
Ÿ Precedence of operators and type conversion of mixed types conform to the C++
language.
Ÿ The number of Original Program Model (OPM) programs in a debug session is
10; there is no limit to the number of ILE programs that can be in a debug
session
Ÿ The maximum number of breakpoints is 1000
Ÿ The maximum size of variables that can be displayed is :
– 65535 characters, with the :c formatting override
– 65535 characters, with the :x formatting override
– 65535 characters, with the :s formatting override; if no count is entered, the
command stops after 30 bytes or a NULL, whichever is encountered first
– 65535 characters, with the :f formatting override; if no count is entered, the
command stops after 1024 bytes or a NULL, whichever is encountered first
Ÿ The maximum number of classes that can be inherited as virtual base classes in a
single compilation unit is 512.

Preparing a Program for Debugging


A program or module must have debug data available if you are to debug it. Since
debug data is created during compilation, you specify one of the /Ti debug options
on the iccas compiler invocation command, to indicate what type of data (if any) is
to be created during compilation.

The type of debug data that can be associated with a module is referred to as a debug
view. With the ILE source-level debugger you can create two views for each module
you want to debug:
Ÿ A listing view
Ÿ A statement view

258 IBM VisualAge C++ for OS/400 C++ User’s Guide


Preparing a Program for Debugging

Note: The default value for the debug option on iccas is /Ti-, which means that
the module being created does not contain debug data. Specify this option if you do
not want debug data to be included with the module ,or if you want faster compila-
tion time.

The storage requirements for a module or program vary somewhat, depending on the
type of debug data included. The debug option are listed below, in increasing order,
based on secondary storage requirements:
1. /Ti- (No debug data)
2. /Tin (Statement view)
3. /Til (Listing view)
4. /Ti+ (All views)

Once you have created a module with debug data and bound it into a program
(*PGM), you can start debugging.
Note: You can specify the /Tis compiler option to create a source view, but in
order to view the source you must use the VisualAge C++ for OS/400 Debugger,
because the C++ source resides on the OS/2 workstation.

Creating a Listing View


A listing view contains text similar to the text in the compiler listing produced by the
compiler. You create a listing view to debug a module by using the /Til or /Ti+
options for the iccas command when you create a module.

The compiler creates the listing view while the module (*MODULE) is being gener-
ated. The listing view is created by copying the text of the appropriate source
members into the module. There is no dependency on the source members upon
which it is based, once the listing view is created.

For example, to create a listing view to debug a program created from the source file
myfile.cpp, type:
iccas /Til myfile.cpp
Note: The maximum line length for a listing view is 255 characters.

Creating a Statement View


A statement view allows the module to be debugged using debug commands.

You create a statement view to debug a module by using the /Tin or /Ti+ option for
the iccas command when you create a module.

Use this view when:

Chapter 16. Using the ILE Source-Level Debugger 259


Starting the ILE Source-Level Debugger

Ÿ You have storage constraints, but do not want to recompile the module or
program if you need to debug it
Ÿ You are sending compiled objects to other users and want to be able to diagnose
problems in your code, without these users being able to see your actual code

To create a statement view to debug a program created from the source file
myfile.cpp, type:
iccas /Tin /L+ myfile.cpp

You debug the program using the debug commands.

Starting the ILE Source-Level Debugger


You start the ILE source-level debugger using the Start Debug (STRDBG) command.
Once the debugger has been started, it remains active until you enter the End Debug
(ENDDBG) command.

You must have *CHANGE authority to a program object to include it in a debug


session. Initially you can add up to ten programs to a debug session by using the
Program (PGM) parameter on the STRDBG command. They can be any combination
of OPM or ILE programs.

If an ILE C++ program with debug data is included in a debug session, the entry
module of the first ILE program specified on the STRDBG command is shown, if it
has debug data. Otherwise, the first module bound to the first ILE program with
debug data is shown.

To start a debug session for a program DBGEXMP that calls program CPPPGM, type:
STRDBG PGM (MYLIB/DBGEXMP MYLIB/CPPPGM)

The Display Module Source display appears. If the entry module has a listing view,
the display shows text similar to the compiler listing of the entry module of the first
program. In this example, the program was created using the compiler option /Ti+.
Therefore, the listing for the main module DBGEXMP appears.
Note: ILE service programs cannot be specified on the STRDBG command. You
can add ILE service programs to a debug session by using option 1 (Add) on the
Work with Module List display display (F14), or by letting the debugger. add it as
part of a STEP INTO debug command.

Setting Debug Options


After you start a debug session, you can set debug options:

260 IBM VisualAge C++ for OS/400 C++ User’s Guide


Adding and Removing Programs from a Debug Session

Ÿ You can indicate whether database files can be updated while debugging your
program.
This option affects the UPDPROD parameter of the STRDBG command. This
parameter specifies whether database files in a production library can be opened
for updating records or for adding new records when the job is in debug mode.
If not, the files must be copied into a test library before trying to run a program
that uses the files.
Ÿ You can also indicate if find operations are case sensitive or case insensitive
during a search request.
When you start a debug session, the default is case insensitive searching.

To set a debug option, type:


SET option value
on the debug command line, where option is an option that you want to set. value
identifies the value of the option.

You can set UPDPROD to update production files and set its value to YES or NO

You can set CASE to define case sensitive or case insensitive searching, and set its
value to MATCH or IGNORE.

For example
SET UPDPROD YES
SET CASE MATCH
allows production files to be updated in debug mode, find operations to be case
sensitive.
Note: If you enter the SET debug command without parameters, the Set Debug
Options display is shown.

Adding and Removing Programs from a Debug Session


You can add more programs and remove programs to be debugged after starting a
debug session. You must have *CHANGE authority to a program to add or remove it
from a debug session.

For ILE programs: Use option 1 (Add program) on the Work with Module List
display entered by using F14 from the Display Module Source display.

To remove an ILE program or service program, use option 4 (Remove program) on


the same display. When an ILE program or service program is removed, all break-
points for that program are removed.

Chapter 16. Using the ILE Source-Level Debugger 261


Viewing the Program Source

There is no limit to the number of ILE programs or service programs that can be in a
debug session at one time.

For OPM programs: Use the Add Program (ADDPGM) command or the Remove
Program (RMVPGM) command. Only 10 OPM programs can be in a debug session at
one time.

Example of Adding a Service Program to a Debug Session


In this example you add the service program SERVEPIO to the debug session which
previously started.
1. If the current display is not the Display Module Source display, type DSPMODSRC
and press Enter. The Display Module Source display appears.
2. Press F14 (Work with module list) to show the Work with Module List display.
3. To add service program SERVEPIO:
a. Select menu item 1 (Add program)
b. Enter SERVEPIO in the Program/module field
c. Enter \LIBL in the Library field.
4. Change the default program type from *PGM to *SRVPGM and press Enter.
5. Press F12 (Cancel) to return to the Display Module Source display.

Example of Removing a Program from a Debug Session


In this example you remove the ILE program CVTIOPGM and the service program
SERVEPIO from a debug session.
1. If the current display is not the Display Module Source display, type
DSPMODSRC. The Display Module Source display appears.
2. Press F14 (Work with module list) to show the Work with Module List display.
3. On this display, type 4 (Remove program) on the lines next to CVTIOPGM and
SERVEPIO, and press Enter.
4. Press F12 (Cancel) to return to the Display Module Source display.

Viewing the Program Source


The Display Module Source display shows the source of a program one module at a
time. A module's source can be shown if the module was compiled using one of the
following debug view compiler options:
Ÿ /Til (Listing view)
Ÿ /Ti+ (All views)

262 IBM VisualAge C++ for OS/400 C++ User’s Guide


Viewing the Program Source

Note: When you compile your source files with the /Ti+ compiler option, the
resulting module object also contains a Source View. In this case, the STRDBG
command should display the Source View, by default. Instead, the Listing View is
shown, because source files are located on your OS/2 workstation, and the Source
View would result in a blank debugger screen.

You can change what is shown on the Display Module Source display by changing
to a different module.

When you change the module, the executable statement on the displayed view is
stored in memory and is viewed when the module is displayed again. Line numbers
that have breakpoints set are highlighted. When a breakpoint, step, or message causes
the program to stop and the display to be shown, the statement where the breakpoint
occurred is highlighted.

Use the Top, Bottom, Up, Left, Right, Next, Previous, and Find commands for
positioning in the Display Module Source display of your module source. See
“Debug Commands for the ILE Source-Level Debugger” on page 256 for a
description of these commands.

Viewing a Different Module


To change the module that is shown on the Display Module Source display, use
option 5 (Display module source) on the Work with Module List display. You
access the Work with Module List display from the Display Module Source display
by pressing F14 (Work with Module List display).

For example, to change from a module MOD1 to a module MOD2 using the Display
module source option, follow these steps:
1. To work with modules, type DSPMODSRC, and press Enter. The Display Module
Source display is shown.
2. Press F14 (Work with module list) to show the Work with Module List display.
3. To select MOD2, type 5 (Display module source) next to it and press Enter. If a
listing view is available, it is shown. Otherwise, you see a blank Display
Module Source display with the message "Module source not available".

An alternate method of viewing a different module is to use the DISPLAY debug


command. On the debug command line, type:
DISPLAY MODULE name

The module name is shown. The module must exist in a program that has been added
to the debug session.

Chapter 16. Using the ILE Source-Level Debugger 263


Setting and Removing Breakpoints

Setting and Removing Breakpoints


You can use breakpoints to halt a program at a specific point when it is running.
Ÿ An unconditional breakpoint stops the program at a specific statement.
Ÿ A conditional breakpoint stops the program when a specific condition at a spe-
cific statement is met.

You set the breakpoints prior to running the program. When the program stops, the
Display Module Source display is shown. The appropriate module is shown with the
source positioned at the line where the breakpoint occurred. This line is highlighted.
At this point, you can evaluate fields, set more breakpoints, and run any of the debug
commands.

You should know the following characteristics about breakpoints before using them:
Ÿ When a breakpoint is set on a statement, the breakpoint occurs before that state-
ment is processed.
Ÿ When a statement with a conditional breakpoint is reached, the conditional
expression associated with the breakpoint is evaluated before the statement is
processed. If the expression is true, the breakpoint takes effect, and the program
stops on that line.
Ÿ If the line on which you want to set a breakpoint is not an executable statement,
the breakpoint is set on the next executable statement.
Ÿ A breakpoint is not processed when the corresponding statement is bypassed.
Ÿ Breakpoint functions are specified through debug commands. These functions
include:
– Adding breakpoints to programs
– Removing breakpoints from programs
– Displaying breakpoint information
– Resuming the running of a program after a breakpoint has been reached
Ÿ To set a breakpoint on the first statement of a multi-statement macro, the cursor
should be on the line containing the macro invocation, not the macro expansion.

Setting and Removing Unconditional Breakpoints


You can set or remove an unconditional breakpoint by using:
Ÿ F6 (Add/Clear breakpoint) from the Display Module Source display
Ÿ F13 (Work with module breakpoints) from the Display Module Source display
Ÿ The BREAK debug command to set a breakpoint
Ÿ The CLEAR debug command to remove a breakpoint

264 IBM VisualAge C++ for OS/400 C++ User’s Guide


Setting and Removing Breakpoints

The simplest way to set and remove an unconditional breakpoint is to use F6


(Add/Clear breakpoint). The function key acts as a toggle. If a breakpoint is already
set on the current line, pressing F6 removes it.

To set or remove an unconditional breakpoint from the Display Module Source


display press F13 (Work with module breakpoints). A list of options appear that
allow you to set or remove breakpoints. If you select 4 (Clear), a breakpoint is
removed from the line.

An alternate method of setting and removing unconditional breakpoints is to use the


BREAK and CLEAR debug commands. To set an unconditional breakpoint using the
BREAK debug command, type:
BREAK line-number

on the debug command line. The variable line-number is the line number in the
currently displayed view of the module on which you want to set a breakpoint.

To remove an unconditional breakpoint using the CLEAR debug command, type:


CLEAR line-number

on the debug command line. The variable line-number is the line number in the
currently displayed view of the module from which you want to remove a breakpoint.

Example of Setting an Unconditional Breakpoint


In this example, you set an unconditional breakpoint using F6 (Add/Clear breakpoint).

To work with a module, type DSPMODSRC and press Enter. The Display Module
Source display is shown.

If you want to set a breakpoint in a different module of the current program, type:
DISPLAY MODULE name

on the debug command line where name is the name of the module that you want to
display.

If you want to set the breakpoint in the module shown, place the cursor on a state-
ment line number where you want to set the breakpoint, and Press F6 (Add/Clear
breakpoint).
Ÿ If there is no breakpoint on the line you specify, an unconditional breakpoint is
set on that line.
Ÿ If there is a breakpoint on the line, it is removed.

Chapter 16. Using the ILE Source-Level Debugger 265


Setting and Removing Breakpoints

After the breakpoint is set, press F3 (Exit) to leave the Display Module Source
display. The breakpoint is not removed.

Call the program. When a breakpoint is reached, the program stops and the Display
Module Source display is shown again, with the line containing the breakpoint high-
lighted. At this point, you can step through the program, resume processing, evaluate
variables, or issue any other debug command.

Setting and Removing Conditional Breakpoints


You can set or remove a conditional breakpoint by using:
Ÿ The Work with Module Breakpoints display
Ÿ The BREAK debug command to set a breakpoint
Ÿ The CLEAR debug command to remove a breakpoint
Note: The relational operators supported for conditional breakpoints are <, >, ==,
<=, >=, and !=.

Using the Work With Module Breakpoints Display


You access the Work with Module Breakpoints display from the Display Module
Source display by pressing F13. The display provides you with a list of options that
allow you to either add or remove conditional and unconditional breakpoints.

Making a Breakpoint Conditional

To make the breakpoint conditional, specify a conditional expression in the Condition


field. If the line on which you want to set a breakpoint is not a executable statement,
the breakpoint is set at the next executable statement.

Calling the Program

Once you have finished specifying all of the breakpoints, you call the program. You
can use F21 (Command Line) from the Display Module Source display to call the
program from a command line or call the program after exiting from the display.

Evaluating a Conditional Expression

When a statement with a conditional breakpoint is reached, the conditional expression


associated with the breakpoint is evaluated before the statement is run.
Ÿ If the result is false, the program continues to run.
Ÿ If the result is true, the program stops, and the Display Module Source display
is shown.

266 IBM VisualAge C++ for OS/400 C++ User’s Guide


Setting and Removing Breakpoints

At this point, you can evaluate fields, set more breakpoints, and run any of the debug
commands.

Using the BREAK and CLEAR Debug Commands


An alternate method of setting and removing conditional breakpoints is to use the
BREAK and CLEAR debug commands.

To set a conditional breakpoint using the BREAK debug command, type:


BREAK line-number WHEN expression

on the debug command line. The variable line-number is the line number in the
currently displayed view of the module on which you want to set a breakpoint.
Expression is the conditional expression that is evaluated when the breakpoint is
encountered. The relational operators supported for conditional breakpoints are noted
at the beginning of this section.

To remove a conditional breakpoint using the CLEAR debug command, type:


CLEAR line-number

on the debug command line. The variable line-number is the line number in the
currently displayed view of the module from which you want to remove a breakpoint.

Example of Setting a Conditional Breakpoint Using F13


In this example, you set a conditional breakpoint using F13 (Work with module
breakpoints).
1. To set a conditional breakpoint, press F13 (Work with module breakpoints) from
the Display Module Source window. The Work with Module Breakpoints
display is shown.
2. On this display, type 1 (Add) on the first line of the list to add a conditional
breakpoint.
3. To set a conditional breakpoint at line 35 when i is equal to 21, type 35 for the
Line field, i==21 for the Condition field, and press Enter.
A conditional breakpoint is set on line 35. The expression is evaluated before
the statement is run. If the result is true (in the example, if i==21), the program
stops, and the Display Module Source display is shown. If the result is false,
the program continues to run.
An existing breakpoint is always replaced by a new breakpoint entered at the
same location.
4. After the breakpoint is set, press F12 (Cancel) to leave the Work with Module
Breakpoints display. Press F3 (End Program) to leave the ILE source-level
debugger. Your breakpoint is not removed.
Chapter 16. Using the ILE Source-Level Debugger 267
Stepping Through the Program

5. Call the program. When a breakpoint is reached, the program stops, and the
Display Module Source display is shown again. At this point, you can step
through the program or resume processing.

Example of Setting a Conditional Breakpoint Using the BREAK Command


In this example, you want to stop the program when the variable j has a certain value.
To specify the conditional breakpoint using the BREAK command:
1. From the Display Module Source display, enter:
break 56 when j==5
A conditional breakpoint is set on line 56.
2. After the breakpoint is set, press F3 (End Program) to leave the ILE source-level
debugger. Your breakpoint is not removed.
3. Call the program. When a breakpoint is reached, the program stops, and the
Display Module Source display is shown again.

Removing All Breakpoints


You can remove all breakpoints, conditional and unconditional, from a program that
has a module shown on the Display Module Source display by using the CLEAR PGM
debug command. To use the debug command, type:
CLEAR PGM

on the debug command line. The breakpoints are removed from all of the modules
bound to the program.

Stepping Through the Program


After a breakpoint is encountered, you can run a specified number of statements of
the program, then stop the program again and return to the Display Module Source
display. You do this by using the step function of the ILE source-level debugger.
The program resumes running on the next statement of the module in which the
program stopped. Typically, a breakpoint is used to stop a program.

You can step through a program by using:


Ÿ F10 (Step) or F22 (Step into) on the Display Module Source display
Ÿ The STEP debug command

The simplest way to step through a program one statement at a time is to use F10
(Step) or F22 (Step into) on the Display Module Source display. When you press
F10 (Step) or F22 (Step into), the next statement of the module shown in the Display
Module Source display is run, and the program is stopped again.

268 IBM VisualAge C++ for OS/400 C++ User’s Guide


Stepping Through the Program

Note: You cannot specify the number of statements to step through when you use
F10 (Step) or F22 (Step into). Pressing F10 (Step) or F22 (Step into) performs a
single step.

Another way to step through a program is to use the STEP debug command. The
STEP debug command allows you to run more than one statement in a single step.
The default number of statements to run is one. To use the STEP debug command,
type:
STEP number-of-statements

on the debug command line. The variable number-of-statements is the number of


statements of the program that you want to run in the next step before the program is
halted again. For example, if you type STEP 5 on the debug command line, the next
five statements of your program are run, the program is stopped again and the
Display Module Source display is shown.

When a CALL statement to another program or procedure is encountered in a debug


session, you can do one of the following:
Ÿ Step over the called program or procedure
Ÿ Step into the called program or procedure

If you choose to step over the called program, the CALL statement and the called
program are run as a single step. The called program is run to completion before the
calling program is stopped at the next step. Step over is the default step mode.

If you choose to step into the called program, each statement in the called program is
run as a single step. If the next step at which the running program is to stop falls
within the called program, the called program is halted at this point and the called
program is shown in the Display Module Source display.

Stepping Over Programs


You can step over programs by using:
Ÿ F10 (Step) on the Display Module Source display
Ÿ The STEP OVER debug command

Using F10 to Step Over Programs


You can use F10 (Step) on the Display Module Source display to step over a called
program in a debug session. If the next statement to be run is a CALL statement to
another program, pressing F10 (Step) causes the called program to run to completion
before the calling program is stopped again.

Chapter 16. Using the ILE Source-Level Debugger 269


Stepping Through the Program

Using the STEP OVER Debug Command


Alternately, you can use the STEP OVER debug command to step over a called
program in a debug session. To use the STEP OVER debug command, type:
STEP number-of-statements OVER

on the debug command line. The variable number-of-statements is the number of


statements of the program that you want to run in the next step before the program is
halted again.

If this variable is omitted, the default is 1. If one of the statements that are run
contains a call to another program, the ILE source-level debugger steps over the
called program.

Stepping Into Programs


You can step into programs by using:
Ÿ F22 (Step into) on the Display Module Source display
Ÿ The STEP INTO debug command

Using F22 to Step Into Programs


You can use F22 (Step into) on the Display Module Source display to step into a
called program in a debug session. If the next statement to be run is a CALL state-
ment to another program, pressing F22 (Step into) causes the first executable state-
ment in the called program to be run. The called program is then shown in the
Display Module Source display.
Note: The called program must have debug data associated with it in order for it to
be shown in the Display Module Source display.

Using The STEP INTO Debug Command


Alternately, you can use the STEP INTO debug command to step into a called
program in a debug session. To use the STEP INTO debug command, type:
STEP number-of-statements INTO

on the debug command line. The variable number-of-statements is the number of


statements of the program that you want to run in the next step before the program is
halted again. If this variable is omitted, the default is 1.

Stepping Into Called Programs


If one of the statements that are run contains a CALL statement to another program,
the source-level debugger steps into the called program. Each statement in the called
program is counted in the step. If the step ends in the called program, the called
program is shown in the Display Module Source display. For example, if you type
STEP 5 INTO

270 IBM VisualAge C++ for OS/400 C++ User’s Guide


Stepping Through the Program

on the debug command line, the next five statements of the program are run. If the
third statement is a CALL statement to another program, two statements of the calling
program are run and the first three statements of the called program are run.

The STEP INTO command works with the CL CALL command as well. You can
take advantage of this to step through your program after calling it. After starting the
source-level debugger, from the initial Display Module Source display, enter
STEP 1 INTO

This sets the step count to 1. Use the F12 key to return to the command line and
then call the program. The program stops at the first statement with debug data.

Example of Stepping Into a Program Using F22


In this example, you use the F22 (Step Into) to step into the program CPPPGM from
the program DEBUGEX.
1. Assume that the Display Module Source Display shows the source for DBGEX
2. To set an unconditional breakpoint at line 92, which is the last executable state-
ment before the call to function CalcTax() in program CPPPGM, type Break and
press Enter.
3. Press F3 (End program) to leave the Display Module Source display.
4. Call the program. The program stops at breakpoint 92, as shown in Figure 58 on
page 272.

Chapter 16. Using the ILE Source-Level Debugger 271


Stepping Through the Program

DBGEX Before Stepping Into CPPPGM

à@ Display Module Source


ð
Program: DEBUGEX Library: MYLIB Module: DBGEX
88 cout << "Please enter amount" << endl;
89 cin >> input;
9ð if (input > MINIMUM) {
91 // call function CalcTax in separate program CPPPGM
92 retval1 = CalcTax(input);
93 if (retval1 > LIMIT)
94 retval2 = CalcSurtax(input)
95 }
96 cout << "Total tax is " << retval1 = retval2 << endl;
97 }
98
99
1ðð
1ð1
1ð2
More...
Debug . . .

F3=End program F6=Add/Clear breakpoint F1ð=Step F11=Display variable


F12=Resume F13=Work with module breakpoints F24=More keys
Breakpoint at line 9ð.
á ñ

Figure 58. Module Source Display for

5. Press F22 (Step into). One statement of the program runs, and then the Display
Module Source display of CPPPGM is shown, as in Figure 59 on page 273.
In this case, the first executable statement of CPPPGM is processed (line 13) and
then the program stops.
Note: You cannot specify the number of statements to step through when you
use F22. Pressing F22 performs a single step.

272 IBM VisualAge C++ for OS/400 C++ User’s Guide


Stepping Through the Program

à@ Display Module Source


ð
Program: CPPPGM Library: MYLIB Module: CPPPGM
1 \===============================================================
2 \ CPPPGM - Program called by DEBUGEX to illustrate the STEP
3 \ functions of the ILE source-level debugger.
4 \
5 \ This program receives a parameter input from DEBUGEX,
6 \ calculates a tax amount, and then returns
7 \===============================================================
8
9 double CalcTax(double input)
1ð{
11 double tax;
12
13 tax= input \ TAXRATE
14 return taxrate;

Bottom
Debug . . .

F3=End program F6=Add/Clear breakpoint F1ð=Step F11=Display variable


F12=Resume F13=Work with module breakpoints F24=More keys
Step completed at line 13.
á ñ

Figure 59. Module Source Display After Stepping Into CPPPGM

Stepping Over Procedures


If you specify over on the STEP debug command, calls to procedures, and functions
count as single statements. This is the default step mode. You can start the step-over
function by using:
Ÿ The STEP OVER debug command
Ÿ F10 (Step)

Stepping Into Procedures


If you specify into on the STEP debug command, each statement in a procedure or
function that is called counts as a single statement. Stepping through four statements
of a program could result in running 20 statements if one of the four is a call to a
procedure with 16 statements. You can start the step into function by using:
Ÿ The STEP INTO debug command
Ÿ F22 (Step into)

The called procedure must have debug data associated with it in order for it to be
shown in the Display Module Source display.

You can automatically put a program or service program into debug. This happens if
the program or service program:

Chapter 16. Using the ILE Source-Level Debugger 273


Displaying the Value of Variables and Expressions

Ÿ Has debug data


Ÿ Is not in debug
Ÿ Contains a procedure that is stepped into from another program in debug

The program or service program is added to debug for you and the Display Module
Source display shows the procedure in the program or service program. From this
point, modules in the program or service program can be accessed using the Work
with Modules List display just like modules in programs you added to debug.

Displaying the Value of Variables and Expressions


You can display the value of scalar variables, expressions, records, structures, classes,
arrays, pointers, enumerations, bit fields, unions, functions using the EVAL debug
command.

There are two ways to display or evaluate:


Ÿ F11 (Display variable)
Ÿ The EVAL debug command

The scope of the variables used in the EVAL debug command is defined by using the
QUAL debug command.

Using F11 to Display Variables


The easiest way to display data or an expression is to use F11 (Display variable) on
the Display Module Source display. To display a variable using F11 (Display vari-
able), place your cursor on the variable that you want to display and press F11
(Display variable). The current value of the variable is shown on the message line at
the bottom of the Display Module Source display.

In cases where you are evaluating structures, records, classes, arrays, pointers, enu-
merations, bit fields, unions or functions, the message returned when you press F11
(Display variable) may span several lines. Messages that span several lines are
shown on the Evaluate Expression display to show the entire text of the message.
Once you have finished viewing the message on the Evaluate Expression display,
press Enter to return to the Display Module Source display.
Note: The Evaluate Expression display also shows all the past debug commands
that you entered and the results from these commands. You can search forward or
backward on the Evaluate Expression display for a specified string, or text, and
retrieve or reissue debug commands.

Using the EVAL Debug Command


To display data using the EVAL debug command, type EVAL variable on the debug
command line. variable is the name of the variable, expression, data structure,

274 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

class, array, pointer, bit-field, union, function or array that you want to display or
evaluate. The value is shown on the message line if the EVAL debug command is
entered from the Display Module Source display and the value can be shown on a
single line. Otherwise, it is shown on the Evaluate Expression display.

Figure 60 shows the result of using the debug command EVAL


HOLD_FORMATTED_COST to display the contents of a variable hold_formatted_cost.

à@ Display Module Source


ð
Program: CPPPG1 Library: CURLIB Module: CPPMOD2
47 if (j<ð) return(ð);
48 if (hold_formatted_cost[i] == '$')
49 {
5ð formatted_cost[j] = hold_formatted_cost[i];
51 break;
52 }
53 if (i<16 && !((i-2)%3))
54 {
55 formatted_cost[j] = ',';
56 --j;
57 }
58 formatted_cost[j] = hold_formatted_cost[i];
59 --j;
6ð }
61
More...
Debug . . . _____________________________________________

F3=End program F6=Add/Clear breakpoint F1ð=Step F11=Display variable


F12=Resume F13=Work with module breakpoints F24=More keys
hold_formatted_cost = SPP:ððððCð48BDððð3Fð
á ñ

Figure 60. Displaying a Variable Using the EVAL Debug Command

You can also use the EVAL debug command to determine the value of an expression.
For example, if j has a value of 1024, if you type eval (j \ j)/512 on the debug
command line the message line shows (j \ j)/512 = 2ð48.

Figure 61 on page 276 shows the use of the EVAL command with pointers, variables,
and bit fields. The pointers, variables, and bit fields are based on the source in
“Sample Source for EVAL Commands” on page 288.

Chapter 16. Using the ILE Source-Level Debugger 275


Displaying the Value of Variables and Expressions

Pointers
/\ Display a pointer \/
>eval pc1
pc1 = SPP:ððððCð26ð9ðð1ð7C

/\ Assign a value to a pointer \/


>eval pc2=pc1
pc2=pc1 = SPP:ððððCð26ð9ðð1ð7C

/\ Dereference a pointer \/
>eval \pc1
\pc1 = 'C'

/\ Take the address of a pointer \/


>eval &pc1
&pc1 = SPP:ððððCð26ð9ðð1ð4ð

/\ Build an expression with normal C precedence \/


>eval \&pc1
\&pc1 = SPP:ððððCð26ð9ðð1ð7C

/\ Casting a pointer \/
>eval \(short \)pc1
\(short \)pc1 = -15616

/\ Treat an unqualified array as a pointer


>eval arr1
arr1 = SPP:ððððCð26ð9ðð1ð7ð

/\ Apply the array type through dereferencing (character in this example)


>eval \arr1
\arr1 = 'A'

/\ Override the formatting of an expression that is an lvalue


>eval \arr1:s
\arr1:s = "ABC"

/\ Set a pointer to null by assigning ð


>eval pc1=ð
pc1=ð = SYP:\NULL

/\ Evaluate a function pointer


>eval fncptr
fncptr = PRP:ððððAðCDððð4Fð1ð

/\ Use the arrow operator \/


>eval \pY->x.p
\pY->x.p = ' '

Figure 61 (Part 1 of 2). Sample EVAL Commands for C Pointers, Variables, and Bit Fields

276 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

Simple Variables

/\ Perform logical operations \/


>eval i1==u1 || i1<u1
i1==u1 || i1<u1 = ð

/\ Unary operators occur in proper order \/


>eval i1++
i1++ = 1ðð

/\ i1 is incremented after being used \/


>eval i1
i1 = 1ð1

/\ i1 is incremented before being used \/


>eval ++i1
++i1 = 1ð2

/\ Implicit conversion \/
>eval u1 = -1ð
u1 = -1ð = 4294967286

/\ Implicit conversion \/
>eval (int)u1
(int)u1 = -1ð

Bit Fields

/\ Display an entire structure \/


>eval bits
bits.b1 = 1
bits.b4 = 2

/\ Work with a single member of a structure \/


>eval bits.b4 = bits.b1
bits.b4 = bits.b1 = 1

/\ Bit fields are fully supported \/


>eval bits.b1 << 2
bits.b1 << 2 = 4

/\ You can overflow bit fields, but no warning is generated \/


>eval bits.b1 = bits.b1 << 2
bits.b1 = bits.b1 << 2 = 4
>eval bits.b1
bits.b1 = ð

Figure 61 (Part 2 of 2). Sample EVAL Commands for C Pointers, Variables, and Bit Fields

Figure 62 on page 278 shows the use of the EVAL command with structures, unions,
and enumerations. The structures, unions, and enumerations are based on the
source in “Sample Source for EVAL Commands” on page 288.

Chapter 16. Using the ILE Source-Level Debugger 277


Displaying the Value of Variables and Expressions

Structures and Unions

/\ Cast with typedefs \/


>eval (struct z \)&zz
(struct z \)&zz = SPP:ððððCðð5AAðð1ðDð

/\ Cast with tags \/


>eval \(c \)&zz
(\(c \)&zz).a = 1
(\(c \)&zz).b = SYP:\NULL

/\ Assign union members \/


>eval u.x = -1ð
u.x = -1ð = -1ð

/\ Display a union. The union is formatted for each definition \/


>eval u
u.y = 4294967286
u.x = -1ð

Enumerations

/\ Display both the enumeration and its value \/


>eval Color
Color = blue (2)
>eval Number
Number = three (2)

/\ Cast to a different enumeration \/


>eval (enum color)Number
(enum color)Number = blue (2)

/\ Assign by number \/
>eval Number = 1
Number = 1 = two (1)

/\ Assign by enumeration \/
>eval Number = three
Number = three = three (2)

/\ Use enums in an expression


>eval arr1[one]
arr1[one] = 'A'

Figure 62. Sample EVAL Commands for C Structures, Unions and Enumerations

Figure 63 on page 279 shows the use of the EVAL command with system and space
pointers. The system and space pointers are based on the source in “Sample
Source for Displaying System and Space Pointers” on page 290.

278 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

System and Space Pointers

/\ System pointers are formatted


:1934:QTEMP :11111111ð \/
>eval pSYSptr
pSYSptr =
SYP:QTEUSERSPC
ðð111ðð

/\ Space pointers return 8 bytes that can be used in System Service Tools \/
>eval pBuffer
pBuffer = SPP:ððððð71ECDððð2ðð

Figure 63. Sample EVAL Commands for System and Space Pointers

Note: You can also use the EVAL command on C++ language features and constructs.
The ILE source-level debugger can display a full class or structure but only with
those fields defined in the derived class. You can display a base class in full by
casting the derived class to the particular base class.

Figure 64 on page 280 shows the use of the EVAL command with C++ language con-
structs. The C++ language constructs are based on the source in “Sample Source
for Displaying C++ Constructs” on page 292. Additional C++ examples are also pro-
vided in the source-level debugger online help.

Chapter 16. Using the ILE Source-Level Debugger 279


Displaying the Value of Variables and Expressions

/\ Follow the class hierarchy (specifying class D is optional): \/


> EVAL \(class D \)this
(\(class D \)this).__vbp1B = SPP:C4ðF5E3D7Fððð49ð
(\(class D \)this).__vbp1D = SPP:C4ðF5E3D7Fððð44ð
(\(class D \)this).d = 4

/\ Follow the class hierarchy (without specifying class D): \/


> EVAL \(D \)this
(\(D \)this).__vbp1B = SPP:C4ðF5E3D7Fððð49ð
(\(D \)this).__vbp1D = SPP:C4ðF5E3D7Fððð44ð
(\(D \)this).d = 4

/\ Look at a local variable: \/


> EVAL VAR
VAR = 1

/\ Look at a global variable: \/


> EVAL ::VAR
::VAR = 2

/\ Look at a class member (specifying this-> is optional): \/


> EVAL this->f
this->f = 6

/\ Look at a class member (without specifying this->): \/


> EVAL f
f = 6

/\ Disambiguate variable ac: \/


> EVAL A::ac
A::ac = 12

/\ Scope operator with template: \/


> EVAL E<int>::ac
E<int>::ac = 12

/\ Cast with template: \/


> EVAL \(E<int> \)this
(\(E<int> \)this).__vbp1B = SPP:C4ðF5E3D7Fððð49ð
(\(E<int> \)this).__vbp1EXTi_ = SPP:C4ðF5E3D7Fððð4ðð
(\(E<int> \)this).e = 5

/\ Assign a value to a variable: \/


> EVAL f=23
f=23 = 23

/\ See all local variables in a single EVAL statement: \/


> EVAL %LOCALVARS
local = 828
this = SPP:C4ðF5E3D7Fððð4ðð
VAR = 1

Figure 64. Sample EVAL Commands for C++ Expressions

280 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

Displaying Data Structures


You display the contents of a data structure as you would any stand-alone variable.
You simply use the data structure name after EVAL to see the entire contents.

Figure 65 shows the entire structure with two elements being displayed. Each
element of the structure is formatted according to its type and displayed.

> EVAL test


test.charValue = 'c'
test.intValue = 1ð

1 struct { //Code evaluated at line 9 where a


2 char charValue //breakpoint was set.
3 unsigned long intValue;
4 } test;
5
6 main(){
7 test.intValue = 1ð;
8 test.charValue = 'c';
9 test.charValue = 11;
1ð }

Figure 65. Using EVAL with Data Structures

Displaying Variables as Hexadecimal Values


You can use the EVAL debug command to display the value of variables in
hexadecimal format. To display a variable in hexadecimal format, type:
EVAL variable-name: x number-of-bytes

on the debug command line. variable-name is the name of the variable that you
want to display in hexadecimal format. 'x' specifies that the variable is to be display
in hexadecimal format. number-of-bytes indicates the number of bytes displayed.

If no length is specified after the 'x', the size of the variable is used as the length. A
minimum of 16 bytes is always displayed. If the length of the variable is less than 16
bytes, the remaining space is filled with zeros until the 16 byte boundary is reached.

Figure 66 on page 282 shows the variable test defined as an eight-byte character
variable. The EVAL command result length is specified as 32 bytes.

Chapter 16. Using the ILE Source-Level Debugger 281


Displaying the Value of Variables and Expressions

> EVAL test: x 32


ððððð 83ðððððð ðððððððA ðððððððð ðððððððð - c..............
ððð1ð ðððððððð ðððððððð ðððððððð ðððððððð - ...............

1 struct { //Code evaluated at line 9 where a


2 char charValue //breakpoint was set.
3 unsigned long intValue;
4 } test;
5
6 main(){
7 test.intValue = 1ð;
8 test.charValue = 'c';
9 test.charValue = 11;
1ð }

Figure 66. Using EVAL with Hexadecimal Values

The result shows that the 32 bytes are formatted, although only the first 8 are mean-
ingful. The left column is an offset in hexadecimal from the start of the variable.
The right column is an EBCDIC character representation of the data.

Displaying Arrays in Character Format


You can use the EVAL debug command to display an array in character format. To
display an array in character format, type:
EVAL array-name: c number-of-characters

on the debug command line. The variable array-name is the name of the array that
you want to display in character format. 'c' specifies the number of characters to
display.

In Figure 67 on page 283 the array must be dereferenced by the * operator. If the *
operator is not entered, the array is displayed as a space pointer. If the dereferencing
operator is used, but the ': c' is not appended to the expression, only the first array
element is displayed. The default length of the display is 1.

282 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

> EVAL \array: c 11


\array1: c 11 = 'ð123456789 '

1 #include <string.h> //Code evaluated at line 6


2 char array1 [11]; //where a breakpoint was set
3 int i;
4 main(){
5 strcpy(array1,"ð123456789");
6 i = ð;
7 }

Figure 67. Using EVAL with Arrays

The result illustrates displaying 11 characters, including a NULL character. The


NULL character appears as a blank.

Displaying NULL Terminated Arrays (Strings) in Character Format


You can use the EVAL debug command to display a NULL terminated array (string) in
character format. To display a NULL terminated array in character format, type:
EVAL array-name: s length of string

on the debug command line. The variable array-name is the name of the array that
you want to display in character format. 's' specifies the length of the string to
display.

In Figure 68 the array must be dereferenced by the * operator. If the * operator is


not entered, the array is displayed as a space pointer. If the dereferencing operator is
used, but the ': s' is not appended to the expression, only the first array element is
displayed.

> EVAL \array: s


\array1: s = "ð123456789 "

1 #include <string.h> //Code evaluated at line 6


2 char array1 [11]; //where a breakpoint was set
3 int i;
4 main(){
5 strcpy(array1,"ð123456789");
6 i = ð;
7 }

Figure 68. Using EVAL with NULL Terminated Arrays

Chapter 16. Using the ILE Source-Level Debugger 283


Displaying the Value of Variables and Expressions

A string length of up to 65535 can follow the s character. Formatting stops at the
first NULL character encountered. If no length is specified, formatting stops after 30
characters or the first NULL character, whichever is less.

You can use the EVAL debug command to display a NULL terminated array (string) in
multi-line character format. To display a NULL terminated array in a newline char-
acter format, type:
EVAL array-name: f

on the debug command line. The variable array-name is the name of the array that
you want to display in character format. 'f' specifies that the newline character
(x'15') is scanned while displaying the string output. When a newline character is
found, the characters following the newline character are displayed at the beginning
of the next line. If the end of the display line occurs the output is wrapped to the
next display line.

Figure 69 shows how text is wrapped to the next line when you specify s: after the
array-name in the EVAL debug command. When you specify f: after the array-name
the characters following the newline character are displayed at the beginning of the
next line.

EVAL with NULL Terminated Arrays in Multi-Line Character Format

> EVAL \testc: s 1ðð


\testc: s 1ðð =
1 "This is the first line. This is the second line. This is t
61 "third line."

> EVAL \testc: f 1ðð


\testc: f 1ðð =
"This is the first line."
"This is the second line."
"This is the third line."

1 #include <string.h> //Code evaluated at line 6


//where a breakpoint was set

2 int main(){
3 char testc[]= {"This is the first line.\nThis is the second line."
4 "\nThis is the third line."};
5 int i;
6 i = 1;
7 }

Figure 69. Using

284 IBM VisualAge C++ for OS/400 C++ User’s Guide


Displaying the Value of Variables and Expressions

Displaying a Template Class and a Template Function


You can use the EVAL debug command to display a template class or a template func-
tion. To display a template class or template function, type:
EVAL template-name

on the debug command line. The variable template-name is the name of the tem-
plate class or template function you want to display.

Figure 70 shows the results of evaluating a template class. You must enter a tem-
plate name that matches the demangled template name. Typedef names are not valid
because the typedef information is removed when the template name is mangled.

> EVAL XX<int>::a


XX<int>::= '1 '

> EVAL XX<inttype>::a


Identifier not found

1 template < class A > //Code evaluated at line 8


2 class XX { //where a breakpoint was set
3 static A a;
4 static B b;
5 };
6 XX<int> x;
7 typedef int inttype;
8 int XX<int>::a =1; //mangled name a__2XXXTi_
9 int XX<inttype>::b = 2; //mangled name b__2XXXTi_

Figure 70. Using EVAL with a Class Template

Figure 71 on page 286 shows the results of evaluating a template function.

Chapter 16. Using the ILE Source-Level Debugger 285


Changing the Value of Scalar Variables

> EVAL XX<int,12>::sxa


XX<int,12>::sxa = '1 '

> EVAL xxobj.xca[ð]


xxobj.xca[ð] = '2 '

1 template < class A, int B> //Code evaluated at lines 8 and 9


2 class XX { //where breakpoints were set
3 static A sxa;
4 char xca[B];
5 public:
6 XX(void) { xca[ð] = 2; }
7 };
8 XX<int,12> xxobj;
9 int XX<int,2\6>::sxa =1;
//same as intXX<int,12>::sxa
//mangled name sxa__2XXXTiSP12_

Figure 71. Using EVAL with a Function Template

Changing the Value of Scalar Variables


You can change the value of scalar variables using the EVAL debug command with an
assignment operator (=). The program must be called and stopped at a breakpoint or
step location to change the value.

To change the value of a variable, type:


EVAL variable-name = value

on the debug command line. variable-name is the name of the variable that you
want to change and value is an identifier, literal, or constant value that you want to
assign to variable variable-name. For example,
EVAL COUNTER=3

changes the value of COUNTER to 3 and shows


COUNTER=3 = 3

on the message line of the Display Module Source display.

Use the EVAL debug command to assign numeric, alphabetic, and alphanumeric data
to variables. When you assign values to a character variable, the following rules
apply:

286 IBM VisualAge C++ for OS/400 C++ User’s Guide


Changing the Value of Scalar Variables

Ÿ If the length of the source expression is less than the length of the target
expression, the data is left justified in the target expression and the remaining
positions are filled with blanks
Ÿ If the length of the source expression is greater than the length of the target
expression, the data is left justified in the target expression and truncated to the
length of the target expression.

The scope of the variables used in the EVAL debug command is defined by using the
QUAL debug command. For example, to change a variable at line 48, type:
QUAL 48

Line 48 is the number within a function to which you want the variables scoped for
the EVAL debug command.
Note: You do not always have to use the QUAL debug command before the EVAL
debug command. An automatic QUAL is done when a breakpoint is encountered or a
step is done. This establishes the default for the scoping rules to be the current stop
location.

Figure 72 shows the results of changing the array element at 1 from $ to #.

EVAL hold_formatted_cost [1] = '#'


hold_formatted_cost[1]= '#' = '#':

//Code evaluated before statement 51 where a breakpoint is set


47 if (j<ð) return(ð);
48 if (hold_formatted_cost[i] == '$')
49 {
5ð formatted_cost[j] = hold_formatted_cost[i];
51 break;
52 }
53 if (i<16 && !((i-2)%3))
54 {
55 formatted_cost[j] = ',';
56 --j;
57 }
58 formatted_cost[j] = hold_formatted_cost[i];
59 --j;
6ð }
61

Figure 72. Using EVAL to Change a Variable

Chapter 16. Using the ILE Source-Level Debugger 287


Sample Source for EVAL Commands

Equating a Name with a Variable, Expression, or Command


You use the EQUATE debug command to equate a name with a variable, expression,
or debug command for shorthand use. You can then use that name alone or within
another expression. If you use it within another expression, the value of the name is
determined before the expression is evaluated. These names stay active until a debug
session ends or a name is removed.

To equate a name with a field, expression or debug command, type:


EQUATE shorthand-name definition

on the debug command line. shorthand-name is the character string that contains
no blanks that you want to equate with a variable, expression, or debug command.
definition is a character string separated from shorthand-name by at least one
blank that is the variable, expression, or debug command that you are equating with
the name. The character strings can be in uppercase, lowercase, or mixed case.

For example, to define a shorthand name called DC which displays the contents of a
variable called COUNTER, type:
EQUATE DC EVAL COUNTER

on the debug command line. Now, each time DC is typed on the debug command
line, the command EVAL COUNTER is performed.

The maximum number of characters that can be typed in an EQUATE command is


144 which is the length of the command line. After any EQUATE commands have
been expanded, the length is limited to 150 characters, which is the maximum
command length. If a definition is not supplied and a previous EQUATE command
defined the name, the previous definition is removed. If the name was not previously
defined, an error message is shown.

To see the names that have been defined with the EQUATE debug command for a
debug session, type:
DISPLAY EQUATE

on the debug command line. A list of the active names is shown on the Evaluate
Expression display.

Sample Source for EVAL Commands


The sample EVAL commands presented in Figure 61 on page 276 and Figure 62 on
page 278are based on the following source:

288 IBM VisualAge C++ for OS/400 C++ User’s Guide


Sample Source for EVAL Commands

#include <iostream.h>
#include <pointer.h>

/\\ POINTERS \\/

_SYSPTR pSys; //System pointer


_SPCPTR pSpace; //Space pointer
int (\fncptr)(void); //Function pointer
char \pc1; //Character pointer
char \pc2; //Character pointer
int \pi1; //Integer pointer
char arr1[] = "ABC"; //Array

/\\ SIMPLE VARIABLES \\/

int i1; //Integer


unsigned u1; //Unsigned Integer
char c1; //Character
float f1; //Float

/\\ STRUCTURES \\/

struct { //Bit fields


int b1 : 1;
int b4 : 4;
} bits;

struct x{ // Tagged structure


int x;
char \p;
};

struct y{ // Structure with


int y; // structure member
struct x x;
};

typedef struct z { // Structure typedef


int z;
char \p;
} z;

z zz; // Structure using typedef


z \pZZ; // Same

typedef struct c { // Structure typedef


unsigned a;
char \b;
} c;

c d; // Structure using typedef

/\\ UNIONS \\/

union u{ // Union
int x;

Chapter 16. Using the ILE Source-Level Debugger 289


Sample Source for Displaying System and Space Pointers

unsigned y;
};

union u u; // Variable using union


union u \pU; // Same

/\\ ENUMERATIONS \\/

enum number {one, two, three};


enum color {red,yellow,blue};
enum number Number = one;
enum color Color = blue;

/\\ FUNCTION \\/

int ret1ðð(void) { return 1ðð;}

main()
{
float dec1;
struct y y, \pY;
bits.b1 = 1;
bits.b4 = 2;
i1 = ret1ðð();
c1 = 'C';
f1 = 1ððe2;
dec1 = 12.3;
pc1 = &c1;
pi1 = &i1;
d.a = 1;
pZZ = &zz;
pZZ->z=1;
pY = &y;
pY->x.p=(char\)&y;
pU=&u;
pU->x=255;
Number=(number)Color;
fncptr = &ret1ðð;
pY->x.x=1; // Set breakpoint here
}

Sample Source for Displaying System and Space Pointers


The sample EVAL command for displaying system and space pointers presented in
Figure 63 on page 279 is based on the following source:

#include <iostream.h>
#include <mispace.h>
#include <pointer.h>
#include <mispcobj.h>
#include <except.h>
#include <lecond.h>
#include <leenv.h>
#include <qtedbgs.h> // From qsysinc

290 IBM VisualAge C++ for OS/400 C++ User’s Guide


Sample Source for Displaying System and Space Pointers

// Link up the Create User Space API


#pragma linkage(CreateUserSpace,OS)
#pragma map(CreateUserSpace,"QUSCRTUS")
void CreateUserSpace(char[2ð],
char[1ð],
long int,
char,
char[1ð],
char[5ð],
char[1ð],
_TE_ERROR_CODE_T \
);

// Link up the Delete User Space API


#pragma linkage(DeleteUserSpace,OS)
#pragma map(DeleteUserSpace,"QUSDLTUS")
void DeleteUserSpace(char[2ð],
_TE_ERROR_CODE_T \
);

// Link up the Retrieve Pointer to User Space API


#pragma linkage(RetrievePointerToUserSpace,OS)
#pragma map(RetrievePointerToUserSpace,"QUSPTRUS")
void RetrievePointerToUserSpace(char[2ð],
char \\,
_TE_ERROR_CODE_T \
);

int main (int argc, char \argv[])


{
char \pBuffer;
_SYSPTR pSYSptr;
_TE_ERROR_CODE_T errorCode;

errorCode.BytesProvided = ð;

CreateUserSpace("QTEUSERSPCQTEMP ",
"QTESSPC ",
1ð,
ð,
"\ALL ",
" ",
"\YES ",
&errorCode
);

//! call RetrievePointerToUserSpace - Retrieve Pointer to User Space


//!! (pass: Name and library of user space, pointer variable
//!! return: nothing (pointer variable is left pointing to start
//!! of user space)
RetrievePointerToUserSpace("QTEUSERSPCQTEMP ",
&pBuffer,
&errorCode);

Chapter 16. Using the ILE Source-Level Debugger 291


Sample Source for Displaying C++ Constructs

// convert the space pointer to a system pointer


pSYSptr = _SETSPFP(pBuffer);

cout << "Space pointer: " << pBuffer << endl;


cout << "System pointer: " << pSYSptr << endl;

return ð;
}

Sample Source for Displaying C++ Constructs


The sample EVAL command for displaying C++ constructs presented in Figure 64 on
page 280 is based on the following source:

// Program demonstrates the EVAL debug command

class A {
public:
union {
int a;
int ua;
};
int ac;
int amb;
int not_amb;
};

class B {
public:
int b;
};

class C {
public:
int ac;
static int c;
int amb;
int not_amb;
};

int C::c = 45;

template <class T> class E : public A, public virtual B {


public:
T e;
};

class D : public C, public virtual B {


public:
int d;
};

class outter {
public:
static int static_i;

292 IBM VisualAge C++ for OS/400 C++ User’s Guide


Sample Source for Displaying C++ Constructs

class F : public E<int>, public D {


public:
int f;
int not_amb;

void funct();
} inobj;
};

int outter :: static_i = 45;

int VAR = 2;

void outter::F::funct()
{
int local;
a=1; //EVAL VAR : Is VAR in global scope
b=2;
c=3;
d=4;
e=5;
f=6;

local = 828;

int VAR;

VAR=1;
static_i=1ð;
A::ac=12;
C::ac=13;
not_amb=32;

not_amb=13;
// Stop here and show:
// EVAL VAR : is VAR in local scope
// EVAL ::VAR : is VAR in global scope
// EVAL %LOCALVARS : see all local vars
// EVAL \this : fields of derived class
// EVAL this->f : show member f
// EVAL f : in derived class
// EVAL a : in base class
// EVAL b : in Virtual Base class
// EVAL c : static member
// EVAL static_i : static var made visible
: by middle-end
// EVAL au : anonymous union members
// EVAL a=49 :
// EVAL au
// EVAL ac : show ambigous var
// EVAL A::ac : disambig with scope op
// EVAL B::ac : Scope op
// EVAL E<int>::ac : Scope op
// EVAL this : notice pointer values
// EVAL (E<int>\)this : change
// EVAL (class D \)this : class is optional
// EVAL \(E<int> \)this : show fields

Chapter 16. Using the ILE Source-Level Debugger 293


Sample Source for Displaying C++ Constructs

// EVAL \(D \) this : show fields

void main()
{
outter obj;
int outter::F::\mptr = &outter::F::b;
int i;
int& r = i;

obj.inobj.funct();

i = 777;

obj.static_i = 2;

// Stop here
// EVAL obj.inobj.\mptr : member ptr
// EVAL obj.inobj.b
// EVAL i
// EVAL r
// EVAL r=1
// EVAL i
// EVAL (A &) (obj.inobj) : reference cast
// EVAL
}

294 IBM VisualAge C++ for OS/400 C++ User’s Guide


Bibliography
This bibliography lists the publications that make up the IBM VisualAge C++ for OS/400 library and publications of related IBM
products referenced in this book. The list of related publications is not exhaustive but should be adequate for most VisualAge
C++ for OS/400 users.
Ÿ Language Reference, S25H-6963-00
The IBM VisualAge C++ for OS/400
Ÿ C Library Reference, S25H-6964
Library
The following books are part of the IBM VisualAge C++ for
OS/400 library. The IBM VisualAge C++ for OS/400
Ÿ LPS: VisualAge C++ for OS/400, GC09-2125
BookManager Library
Ÿ VisualAge C++ for OS/400 Read Me First!, SC09-2114 The following documents are available in VisualAge C++ for
OS/400 in BookManager format.
Ÿ VisualAge C++ for OS/400 C++ User’s Guide, SC09-2116
Ÿ LPS: VisualAge C++ for OS/400, GC09-2125
Ÿ VisualAge C++ for OS/400 C++ Programming Guide,
SC09-2123 Ÿ VisualAge C++ for OS/400 Read Me First!, SC09-2114
Ÿ VisualAge C++ for OS/400 C++ Language Reference, Ÿ VisualAge C++ for OS/400 C++ User’s Guide, SC09-2116
SC09-2121
Ÿ VisualAge C++ for OS/400 C++ Programming Guide,
Ÿ VisualAge C++ for OS/400 IBM Open Class Library and SC09-2123
IBM Access Class Library for OS/400 User’s Guide,
Ÿ VisualAge C++ for OS/400 C++ Language Reference,
SC09-2117
SC09-2121
Ÿ VisualAge C++ for OS/400 IBM Open Class Library and
Ÿ VisualAge C++ for OS/400 IBM Open Class Library and
IBM Access Class Library for OS/400 Reference,
IBM Access Class Library for OS/400 User’s Guide,
SC09-2120
SC09-2117
Ÿ VisualAge C++ for OS/400 C Library Reference,
Ÿ VisualAge C++ for OS/400 IBM Open Class Library and
SC09-2119
IBM Access Class Library for OS/400 Reference,
SC09-2120

The IBM VisualAge C++ for OS/2 Ÿ VisualAge C++ for OS/400 C Library Reference,
SC09-2119
Library
Ÿ Read Me First!, S25H-6956
The following books are part of the IBM VisualAge C++ for Ÿ Welcome to VisualAge C++ for OS/2, S25H-6957
OS/400 library.
Ÿ User's Guide, S25H-6961
Ÿ Read Me First!, S25H-6956
Ÿ Programming Guide, S25H-6958
Ÿ Welcome to VisualAge C++ for OS/2, S25H-6957
Ÿ Visual Application Builder User's Guide, S25H-6960
Ÿ User's Guide, S25H-6961
Ÿ Visual Application Builder Parts Reference, S25H-6967
Ÿ Programming Guide, S25H-6958
Ÿ Building VisualAge C++ for OS/2 Parts for Fun and
Ÿ Visual Application Builder User's Guide, S25H-6960 Profit, S25H-6968
Ÿ Visual Application Builder Parts Reference, S25H-6967 Ÿ Open Class Library User's Guide, S25H-6962
Ÿ Building VisualAge C++ for OS/2 Parts for Fun and Ÿ Open Class Library Reference, S25H-6965
Profit, S25H-6968
Ÿ Language Reference, S25H-6963-00
Ÿ Open Class Library User's Guide, S25H-6962
Ÿ C Library Reference, S25H-6964
Ÿ Open Class Library Reference, S25H-6965

 Copyright IBM Corp. 1995 295


C and C++ Related Publications IBM OS/2 2.1 Publications
Ÿ Portability Guide for IBM C, SC09-1405
The following books describe the OS/2 2.1 operating system
Ÿ American National Standard for Information Systems / and the Developer's Toolkit 2.1.
International Standards Organization — Programming
Ÿ OS/2 2.1 Using the Operating System, S61G-0703
Language C (ANSI/ISO 9899-1990[1992])
Ÿ OS/2 2.1 Installation Guide, S61G-0704
Ÿ Draft Proposed American National Standard for Informa-
tion Systems — Programming Language C++ Ÿ OS/2 2.1 Quick Reference, S61G-0713
(X3J16/92-0060) Ÿ OS/2 2.1 Command Reference, S71G-4112
Ÿ OS/2 2.1 Information and Planning Guide, S61G-0913
IBM AS/400 Publications Ÿ OS/2 2.1 Keyboard and Codepages, S71G-4113
Ÿ OS/2 2.1 Bidirectional Support, S71G-4114
The following books describe information you need to write
C++ applications that run on the AS/400 system. Ÿ OS/2 2.1 Book Catalog, S61G-0706
Ÿ ADTS/400: Programming Development Manager, Ÿ Developer's Toolkit for OS/2 2.1: Getting Started,
SC09-1771 S61G-1634
Ÿ Application Display Programming, SC41-4715
Ÿ Backup and Recovery – Advanced, SC41-4305 IBM OS/2 3.0 Publications
Ÿ CL Programming, SC41-4721
Ÿ User's Guide to OS/2 Warp, G25H-7196-01
Ÿ CL Reference, SC41-4722
The following books make up the OS/2 3.0 Technical Library
Ÿ COBOL/400 User’s Guide, SC09-1812 (G25H-7116).
Ÿ Communications Management, SC41-3406 Ÿ Control Program Programming Guide, G25H-7101
Ÿ Data Management, SC41-4710 Ÿ Control Program Programming Reference, G25H-7102
Ÿ DB2 for OS/400 Database Programming, SC41-4701 Ÿ Presentation Manager Programming Guide - The Basics,
Ÿ DDS Reference, SC41-3712 G25H-7103
Ÿ Distributed Data Management, SC41-4307 Ÿ Presentation Manager Programming Guide - Advanced
Topics, G25H-7104
Ÿ ICF Programming, SC41-3442
Ÿ Presentation Manager Programming Reference,
Ÿ IDDU Use, SC41-3704
G25H-7105
Ÿ ILE COBOL/400 Programmer’s Guide, SC09-2072
Ÿ Graphics Programming Interface Programming Guide,
Ÿ ILE Concepts, SC41-4606 G25H-7106
Ÿ ILE RPG/400 Programmer’s Guide, SC09-2074 Ÿ Graphics Programming Interface Programming
Reference, G25H-7107
Ÿ Machine Interface Functional Reference, SC41-4810
Ÿ Workplace Shell Programming Guide, G25H-7108
Ÿ Machine Interface Functional Reference, SC24-5739
Ÿ Workplace Shell Programming Reference, G25H-7109
Ÿ Printer Device Programming, SC41-3713
Ÿ Information Presentation Facility Programming Guide,
Ÿ RPG/400 User’s Guide, SC09-1816
G25H-7110
Ÿ System API Reference, SC41-4801
Ÿ OS/2 Tools Reference, G25H-7111
Ÿ Tape and Diskette Device Programming, SC41-4716
Ÿ Multimedia Application Programming Guide, G25H-7112
Ÿ Multimedia Subsystem Programming Guide, G25H-7113
Ÿ Multimedia Programming Reference, G25H-7114
Ÿ REXX User's Guide, S10G-6269

296 IBM VisualAge C++ for OS/400 C++ User’s Guide


Ÿ REXX Reference, S10G-6268 Non-IBM Publications
Many books have been written about the C++ language and
related programming topics. The authors use varying
Other Books You Might Need approaches and emphasis. The following is a sample of some
non-IBM C++ publications that are generally available. This
The following list contains the titles of IBM books that you sample is not an exhaustive list. IBM does not specifically
might find helpful. These books are not part of the recommend any of these books, and other C++ books may be
VisualAge C++ for OS/400 or operating system libraries. available in your locality.
Ÿ The Annotated C++ Reference Manual by Margaret A.
BookManager READ/2 Publications Ellis and Bjarne Stroustrup, Addison-Wesley Publishing
Ÿ IBM BookManager READ/2: General Information, Company.
GB35-0800 Ÿ C++ Primer by Stanley B. Lippman, Addison-Wesley
Ÿ IBM BookManager READ/2: Getting Started and Quick Publishing Company.
Reference, SX76-0146 Ÿ Object-Oriented Design with Applications by Grady
Ÿ IBM BookManager READ/2: Displaying Online Books, Booch, Benjamin/Cummings.
SB35-0801 Ÿ Object-Oriented Programming Using SOM and DSOM by
Ÿ IBM BookManager READ/2: Installation, GX76-0147 Christina Lau, Van Nostrand Reinhold.
Ÿ OS/2 C++ Class Library: Power GUI Programming with
C Set ++ by Kevin Leong, William Law, Robert Love,
Hiroshi Tsuji, and Bruce Olson, John Wiley & Sons, Inc.

Bibliography 297
298 IBM VisualAge C++ for OS/400 C++ User’s Guide
Index
activation group (continued)
Special Characters and OPM programs 189
_ (underscore) character 60 defined 188
:: (colons), used for environment variable 90 delete 192
/? (query) option 120 for OPM programs 189
? (single wild card) in file names 60 identifying 189
@ (atsign) 46 named 189
* (wild card) in file names 60 named, reclaim 189
\ (continuation character) 66 named, running a program in 189
#pragma map directive 60 of calling program 194
+|- (on and off) switches in a compiler option 92 persistence 192
= (equal sign) not allowed in environment variable 90 running a program in 191
> (redirection symbol) 78 adding
objects to a debug session 261
program to be debugged 216
Numerics Program window 217
40 optimization level 75 service program to a debug session 262
alignment and packing of data items 113
allocating storage at run-time 196
A ANSI
abstract code units (ACUs) inlined 82 C++ semantics 194
accumulation of search paths 69 compatibility 112
ACSSBMGT command 43 language level 70
ACTGRP parameter API
defined 189 See application programming interface
non-ANSI behavior 194 application pane 215
set to *CALLER 194 application programming interface
ACTGRP(*NEW), specifying 131 to integrated file system 117
action AS/400
Bind 14 communication to OS/2 38
Build 13 connecting to OS/2 41
Compile 13 disconnecting from OS/2 47
context-sensitive, in WorkFrame 10 file naming conventions 59
Debug 13 host server sessions 41
default, defined 5 issuing CRTSRVPGM 144
Edit 13 publications 296
group 12 running a program from 179
in WorkFrame, defined 5 /as400command parameter 45
Make 14 /ASa option 120
actions /AScp option 121
for OS/2 projects 11 /ASd compiler option 98
for OS/400 projects 12 /ASi code generation options 117, 118
table of, in WorkFrame 10 /ASl compiler option 98
activation /ASn option 121
defined 188 /ASNname parameter
activation group for CTTCONN command 42

 Copyright IBM Corp. 1995 299


/ASNname parameter (continued) binding (continued)
for CTTDIS command 48 directories, defined 129
of CTTHCMD command 45 program to a non-existing service program 165
/ASl compiler option 99 program to a service program 141
/ASt option 122 service program to a program 148
/ASv3r1 option 122 service programs to modules 129
atsign (@) 46 boot, what to do about connection 48
ATTR debug command 256 BOTTOM debug command 257
authority BREAK debug command
required to use debugger 201 definition 256
to modules and programs 120 using 265, 267
automatic storage, limits 72 breakpoint
automatically maintaining precompiled header files 80 conditional 266
delete all 238
line, setting 220
B list 222, 238
/B compiler option removing all 268
invoking CRTPGM setting 211
invoking CRTPGM 132 setting and removing 264
invoking CRTSRVPGM testing 264
issue CRTRVPGM 143 unconditional 264
/B option 122 Breakpoints
back end vs. front end, defined 37 List window 250
backslash (\) 66 menu 219
*BASIC optimization level 75 browsing
Bind action 14 from within WorkFrame 26
bindable APIs source files 25
CEECZST (Reallocate Storage) 196 Build action 13
CEEFRST (Free Storage) 196 Build Smarts
CEEGTST (Get Heap Storage) 196 effect of 22
Free Storage (CEEFRST) 196 setting compiler options 22
Get Heap Storage (CEEGTST) 196
Reallocate Storage (CEECZST) 196
binder C
invoking to create a service program 142 /C compiler option
invoking, in WorkFrame 25 C/400, program entry procedure (PEP) 128
passing the binding command string 122 CALL command 180
binder language passing parameters 186
creating a source file 153 processing parameters 187
reasons for using 152 call stack 192
binder listing *CALLER
creating 135 activation group 191
determining exports from service program 151 parameter 194
sample 135 calling
sections 135 a program 179
working with exports from service program 151 CCSID (coded character set ID), specifying 121
binding changing
and running a program, overview 125 module or program object, purpose 135
avoiding 123 optimization level of program or module 137
defined 127 program order for unresolved import requests 164

300 IBM VisualAge C++ for OS/400 C++ User’s Guide


changing (continued) code generation options (continued)
service program 144 /O code generation options 118
value of scalar variables, while debugging 286 /Oi code generation options 119
char variables, set to signed char 123 performance data 118
character arrays, displaying 282 using integrated file system APIs 117
CHGMOD, removing observability 138 code page number, specifying 121
CHGPGM, removing observability 138 coded character set ID (CCSID), specifying 121
choosing collect performance data 118
from multiple compilers 57 colons (::) used for environment variable 90
language level 70 color window 241
circular references, example 159 combining
CL commands C and C++ files 51, 52
ACSSBMGT 43 ICCAS and OS/2 compiler options 90
Add Program (ADDPGM) 262 multiple source files 51
additional service program commands 145 command file
CALL 180 CTTHCMD command 46
CHGPGM and CHGMOD usage 138 setting environment variables 65
CRTPGM 130, 131 command, equating a name during debugging 288
CRTSRVPGM 143 comments in preprocessing 115
CTTCONN 41, 42 communication between OS/2 and AS/400 38
CTTDIS 47 Communication Manager, starting 40
CTTEND 47 Compile action 13
CTTHCMD 45, 46 compiler
CTTQCONN 44 invoking from WorkFrame 23
DSPMODSRC 262 compiler options
DSPMODSRC) 262 /ASd 98
ENDDBG 260 /ASl 98
invoking through CTTHCMD 129 /ASr 99
issuing from OS/2 45 classification by function 95
RCLACTGRP 189 combining 90
RCLRSC 193 conflicting 94
RMVPGM 262 containing a string parameter 91
STRDBG 260 creating
TFRCTRL 181 *MODULE object 100
UPDPGM 137 browser file 99
user-created 183 files for template resolution 101
WRKACTJOB 48 intermediate code file 101
CLEAR debug command listing file 100
definition 257 precompiled header file 100
removing all breakpoints 268 defaults 53
client/server /Fb 99
applications, developing with WorkFrame 14 /Fc 99
OS/2-OS/400 applications 14 /Fi 100
close debugger 234 file names, extensions, and paths 92
code files, intermediate output 74 /Fl 100
code generation options /Fo 100
/ASi code generation options 117, 118 /Ft 101
control inlining 119 /Fw 101
control optimization 118 HPFS names 92
notes 117 interrelated 94

Index 301
compiler options (continued) controlling (continued)
list of 95 inlining 119
online listing 50 optimization in code generation 118
output management 97 optimization level 75
parameters 91 preloading 123
precedence 90 preprocessor #line directives 116
replacing a module object 99 redirection of preprocessor output 116
saving header files 98 search paths for #include files 102
scope 93 size of enum variables 114
setting in Build Smarts 22 conventions for file naming 59
setting in notebook 22 cooperative compiler 37
special scope cases 93 .cpp file extension 61
summary 95 Create Module command, granting authority 120
switches (+|-) 92 Create Program (CRTPGM) command
syntax check only 99 ANSI C++ compliance 194
syntax for xviii how to issue 131
target library for objects 98 invoking
using numbers 92 invoking from WorkFrame 132
Compiler Options notebook parameters 130
using 22 preparing 131
compiling system actions 134
a C++ program 203 using 130
an ILE program 203 creating
component binder language source file 153
show all 224 binder listing 135
sort 224 browser file 99
compressing an object 138 files for template resolution 101
conditional breakpoint intermediate code file 55, 101
defined 264 listing file 100
setting and removing 266 listing view 259
setting, example 267 make file 171
CONFIG.SYS file 64 *MODULE object 100
configuring the debugger 202 precompiled header file 100
conflicting compiler options 94 precompiled header files automatically 80
connected mode compiling 54 programs, overview 127
connecting OS/2 to AS/400 41 service program, invoking the binder 142
connection statement view 259
interrupted, recovering 48 creating source files 20
multiple between OS/2 and AS/400 43 cross-reference table of variables in listing file 104
name 42 cross-reference table, plus local variables, in listing 108
name, specifying 43 CRTSRVPGM command parameters 142
to host, naming 121 CRTSRVPGM command, issuing 143
constructs, displaying, sample source 292 CTTASENV.CMD command file in OS/2 65
continuation character (\) 66 CTTCONN command 41
controlling CTTDIS command 47
and grouping error messages 109 CTTDIS command, ASnname parameter 48
compiler input 59 CTTEND command 47
error messages 77 CTTHCMD command
#include search path 67 invoking though CL 129
inclusion of comments in preprocessor 115 overview 45

302 IBM VisualAge C++ for OS/400 C++ User’s Guide


CTTHCMD command (continued) debugging (continued)
used to invoke CRTPGM 133 EQUATE command 257
used to issue CRTSRVPGM 144 EVAL command 257
CTTHCMD.EXE command file, renaming 47 FIND command 257
CTTQCONN command 44 from within WorkFrame, preparing for 27
CTTTIME, synchronizing system times 174 general discussion 255
cumulative compiler options 93 HELP command 257
customizing WorkFrame 6 ILE source-level debugger 256
.cxx file extension 61 invocation methods 28
invoking from WorkFrame 28, 207
LEFT command 257
D limitations of debug expression grammar 258
/D preprocessor option 115 limits 212
database data, updating while debugging 260 NEXT command 257
DBCS (double-byte character set) source file 113 OPM program limit in debug session 262
Debug action 13 optimization effects 137, 256
debug commands performance considerations 212
DISPLAY 263 preparing a program 258
general discussion 256 PREVIOUS command 257
STEP 268, 269 QUAL command 257
STEP and STEP OVER 273 removing an object from a session 261
STEP INTO 270, 273 RIGHT command 257
STEP OVER 269 SET command 257
debug data setting and removing breakpoints 264
creating 258 setting debug options 260
effect on object size 259 starting the source-level debugger 260
removing from a module 138 STEP command 257
debug server stepping through a program 268
ending 201 TOP command 257
starting 202 UP command 257
Debug Session Control window 215 updating production files 260
debug view viewing a second module 263
definition 258 viewing source 262
preparing a program for debugging 258 debugging and diagnostic options
debugger all options on or off 108
close 219 controlling and grouping errors 109
configuring 28 message count limit 108
intermediate files 76 /N option 108
ports 202 serverity level of countable errors 109
properties 225 /Ti option 108
required authorities 201 /W option 109
debugging /Wgrp option 109
adding an object to a session 261 decompressing an object 138
an application 27 default
ATTR command 256 heap 195
BOTTOM command 257 language level, defined 71
BREAK command 256 options with iccas 53
CLEAR command 257 project icon, modifying 18
DISPLAY command 257 deleting
DOWN command 257 activation group 192

Index 303
deleting (continued)
all breakpoints 222 E
designating target library for objects 98 Edit action 13
DETAIL parameter, creating a binder listing 135 editing source files 21
development tools, choosing 9 encapsulated code, maximum size 72
DFTACTGRP parameter on CRTBNDRPG ending
*DFTACTGRP symbol 189 connection to AS/400 47
diagnostic options debug server 203
See debugging and diagnostic options debugging session 207
difference between program and service program 141 ILE source-level debugger 260
different platforms, compiling on 57 job running on AS/400 48
digits in a compiler option 92 program 188
directing entry procedure, entry module 131
intermediate code files 101 enum variables, controlling size 114
location of new listing file 100 environment variables
directory for compiler 62
for a listing file 100 ICCAS_DIR 29
working, in WorkFrame 19 ICCAS_DRIVE 29
disconnected setting in CONFIG.SYS 64
AS/400 job 48 setting in CTTASENV.CMD 65
mode compiling 54 setting with ICCAS 66
disconnecting from AS/400 47 environment variables for debugging 203
DISPLAY debug command equal sign (=) not allowed in environment variable 90
definition 257 EQUATE debug command
using 263 definition 257
Display Style window 244 equating a name with a variable expression, or command
displaying during debugging 288
arrays, while debugging 274 erasing precompiled header file 80
character arrays, while debugging 282 error codes 78
constructs, sample source 292 error count limit for compilation 108
data structure, example 281 error messages
expressions, while debugging 274 controlling 77
list of other options 120 controlling and grouping 109
NULL terminated character array, example 283 counting 109
scalar variables, while debugging 274 escape sequence used in a string option 91
structures, while debugging 274 establishing multiple connections between OS/2 and
system and space pointers, sample source 290 AS/400 43
templates, while debugging 285 EVAL debug command
value of variables and expressions 274 definition 257
value of variables and expressions, example 275 sample source 288
variables as hexadecimal values 281 using 274
variables, while debugging 274 example of updating 170
double-byte character set source file 113 exhausted system storage 193
DOWN debug command exiting the ILE source-level debugger 260
definition 257 expand all #include files in listing 106
DPATH environment variable 62 expand user and system #include files in listing 106
duplicate variable names 134 expanded macros in listing file 104
dynamic storage 195 EXPORT keyword, duplicate names 134
allocating storage during run-time 196 export list
example of updating 166

304 IBM VisualAge C++ for OS/400 C++ User’s Guide


expression, equating a name during debugging 288
expression, monitor 238 G
extended language level 70 generating performance data 118
extensions used in a compiler option 92 Get Heap Storage (CEEGTST) bindable API 196
extensions, file 61 grouping error messages 109
externally described files, search order 68

H
F .h file extension 61
FAT vs. HPFS file naming 59 header files
/Fb compiler option 99 created by #pragma mapinc 68
/Fc compiler option 99 default file extensions 61
/Fi compiler option 100 location and time stamp 80
field, preserving values while debugging 256 precompiled 79
file management of compiler options 97 saving 98
file names search path 80
HPFS consideration 47 heap
naming conventions 59 default 195
used in a compiler option 92 defined 195
using wild cards 60 example 196
File Page 20 help xix
file search path contextual xix, 7
preventing use of INCLUDE_ASV3R6 and for WorkFrame 7
INCLUDE_ASV3R1 paths 103 from the command line xxi
specifying 103 How Do I... xix, 7
stopping 103 inside VisualAge C++ for OS/400 xx
file types online 7
input 61 online documents xix
output 73 HELP debug command
files definition 257
compiler option parameters for 92 hexadecimal display of variables 281
for template resolution, creating 101 hide debugger on run 223
FIND debug command /Hname parameter 41
definition 257 host path, mounting as a network drive 173
Find Procedure window 219 host server sessions on the AS/400 41
finding host used to invoke CRTPGM 134
C++ source code 208 host vs. workstation time stamps 174
ILE source code 208 How Do I...
/Fl compiler option 100 help for WorkFrame 7
/Fo compiler option 100 HPFS
folder consideration when expanding INCLUDE_ASV3R6
Free Storage (CEEFRST) bindable API 196 and 106
freeing resources of ILE programs 193 consideration when renaming 47
front end vs. back end, defined 37 names in a compiler option 92
/Ft compiler option 101
*FULL optimization level 75
/Fw compiler option 101 I
.i file extension 61
ICCAS
combined OS/2 compiler options 90

Index 305
ICCAS (continued) #include search path 67
compiler options compared to optimization levels 75 INCLUDE_ASV3R1 environment variable 57, 63
environment variable 63 INCLUDE_ASV3R6 environment variable 57, 63
used to set environment variables 66 incompatible compiler options 94
iccas command 48 Inheritance Page 20
ICCAS_DIR environment variable for MakeMake 29 inlining during code generation 119
ICCAS_DRIVE environment variable for MakeMake 29 inlining user code 81
ICCAS, specifying compiler options 90 abstract code units (ACUs) 82
ICCASCP environment variable 63 benefits 83
ICCASDBGPORT 203 compiler option 81
ICCASDEBUGHOST 203 drawbacks 84
ICCASDEBUGPATH 203 further improvements 84
ICCASHOST keyword 81
environment variable 42, 64 restrictions 85
used to issue CRTSRVPGM 143 when to use 84
ICCASNAME environment variable 42, 64 input, controlling 59
ICCASTAB 203 integrated file system
ICCASUPRD 203 APIs, using 117
identifiers intermediate file
in listing file 104 avoiding 57
maximum length 72 creating only 55
ILE bound calls 72 creating, and transferring to AS/400 39
ILE C/400, program entry procedure (PEP) 128 output 74
ILE source debugger producing 101
debug commands 256 internal
description 256 names 60
limits 258 structure of a program object 128
starting 260 invoking
import requests, unresolved binder to create a program 130
changing program order 164 binder to create a service program 142
handling with *UNRSLVREF 163 CL commands through CTTHCMD 129
imports, resolved by the binder 134 compiler 48
#include directive 66 CRTPGM from the AS/400 134
INCLUDE environment variable 57 CRTPGM from WorkFrame 132
#include file name syntax 66 CRTPGM with /B compiler option 132
include file search option CRTPGM with CTTHCMD 133
controlling search paths for #include files 102 debugger from WorkFrame 207
/I file search option 103 the browser 26
preventing search path 103 ISO compliance 194
preventing use of INCLUDE_ASV3R6 and issuing
INCLUDE_ASV3R1 paths 103 AS/400 CL commands 45
restrictions 102 CRTPGM command 131
specifying search path 103 CRTSRVPGM command 143
usage notes 102
/Xc option 103
/Xi option 103 J
#include files /J option 123
See also header files job logs on AS/400 79
controlling search paths 102
user and system 106

306 IBM VisualAge C++ for OS/400 C++ User’s Guide


listing file options (continued)
K title of listing 107
keyword for inlining user code 81 usage notes 103
variables, information about 104
listing view, creating 259
L /Lj listing file option 106
/L listing file option 104 local compiler options 93
/La listing file option 105 local variables, plus cross reference table, in listing 108
language level locating project parts 19
choosing 70 locating source code 208
compatible 71 location of precompiled header files 80
extended 71 logo, prevent from appearing 123
setting 70, 112 /Lp listing file option 106
/Lb listing file option 105 /Ls listing file option 107
/Le listing file option 105 /Lt listing file option 107
LEFT debug command /Lu listing file option 107
definition 257 /Ly listing file option 108
length of identifiers and procedure names 72
/Lf listing file option 106
/Li listing file option 106 M
limitations of debug expression grammar 258 macros
limits of source-level debugger 258 defined for the preprocessor 115
line breakpoint 220 expanded, in listing file 104
Line Breakpoint window 220 language levels 70
#line directives, controlling 116 undefine during preprocessing 117
listing file maintaining precompiled header files 80
created, named, and directed 100 Make action 14
output 77 make file
listing file options compiling from 49
all options on or off 106 conditions and restrictions 173
cross-reference table, plus local variables, in listing 108 contents 171
expand #include files in listing 106 creating 171
including source program in listing file 104 creation utility MakeMake 29
/L option 104 example 176
/La option 105 format 172
/Lb option 105 mismatch between host and workstation time stamp 174
/Le option 105 restrictions on time stamps 174
/Lf option 106 scope of synchronizing OS/2 workstation and the
/Li option 106 AS/400 175
/Lj option 106 synchronizing system times with CTTTIME 174
/Lp option 106 MakeMake
/Ls option 107 ICCAS_DIR environment variable 29
/Lt option 107 ICCAS_DRIVE environment variable 29
/Lu option 107 using for OS/400 projects 29
/Ly option 108 managing
page length of a listing 106 default heap 195
producing a listing of struct and union variables 105 run-time storage 195
show expanded macros in listing 105 manuals xix
source code included in listing 107 maximum error count for compilation 108
subtitle of listing 107

Index 307
Menu Page 20 NEXT debug command
messages definition 257
controlling 77 *NONE optimization level 75
count limit for compilation 108 NULL terminated character arrays, displaying 283
module numbers in a compiler option 92
and program authority 120
binding to service programs 129
changing optimization level 137 O
determining the entry module 131 /O code generation option 118
effect of debug data on size 259 object
observability, removing 138 reducing size 138
preparing for debugging 258 target library, designating 98
reducing size 138 objects
relationship to program 128 OS/2 and OS/400, correspondence 10
removing observability 138 observability, defined 138
replacing in a program 137 /Oi code generation option 119
viewing source while debugging 262 /Oi option for inlining user functions 81
*MODULE object, creating 100 online information xix
module objects open new module 217, 218, 234
compiled from source code 39 OPM programs and activation groups 189
intermediate output 74 optimizing
maximum number 72 control in code generation 118
purpose of changing 135 definition 137
replacing 99 effect on fields when debugging 256
text description 122 inlining user code 81
module path, show 224 levels 75
module, open new 217, 234 object code 74
monitor expression 238 with debugger 76
Monitor Page 19 OPTION parameter
monitor properties 227 coordinating listing and debug view options 259
mounting a host path as a network drive 173 coordinating statement and debug view options 259
multiple compilers, choosing 57 options, compiler
multiple connections to OS/2 43 See compiler options
OS-linkage, program call 72
OS/2
N combined with ICCAS compiler options 90
/N debugging option 108 communication with AS/400 38
named activation group connecting with AS/400 41
persistence 192 disconnecting from AS/400 47
reclaiming 189 FAT vs. HPFS 59
running a program in 189 file naming conventions 59
names of files 59 issuing CRTSRVPGM 143
naming multiple connections to AS/400 43
*MODULE object 100 publications 296
connection to host 121 reboot, result 48
intermediate code file 101 specifying compiler options 89
listing file 100 other options
network drive, mounting as a host path 173 /? option 120
*NEW to create activation group 190 /ASa option 120
/AScp option 121

308 IBM VisualAge C++ for OS/400 C++ User’s Guide


other options (continued) passing (continued)
/ASn option 121 parameters to a program 186
/ASt option 122 PATH environment variable 62
/ASv3r1 option 122 path names used in a compiler option 92
compile only, no binding 123 /Pc preprocessor option 115
compiler logo 123 /Pd preprocessor option 116
control preloading 123 .pdb files 76
display a list 120 /Pe preprocessor option 116
include version string 124 performance data, generate 118
/J option 123 #pragma mapinc 98
name of connection to host 121 search order for files
notes 119 for files 68
passing the binding command string to binder 122 precedence of compiler options 90
/Q option 123 precompiled header files
set unspecified char variables to signed char 123 compiling with 112
specify coded character set ID 121 creation 79, 100
specify module and program authority 120 location and time stamp 80
targeting the V3R1 run-time environment 122 maintaining automatically 80
text description of module object 122 missing 80
/Tl option 123 restrictions 81
/V option 124 search path 80
output preloading, control 123
AS/400 job logs 79 preparing
file types 73 a program for debugging 258
from compile 53 for using the CRTPGM command 131
from preprocessor, control redirection 116 preprocessed files, default extensions 61
of intermediate code files 74 preprocessing only, no compile 115
to file 78 preprocessor options
control #line directives 116
control comments 115
P control output 116
/P preprocessor option 115 /D preprocessor option 115
packing and alignment of data items 113 defining a preprocessor macro 115
Page /P preprocessor option 115
File 20 /Pc preprocessor option 115
Inheritance 20 /Pd preprocessor option 116
Menu 20 /Pe preprocessor option 116
Monitor 19 run the preprocessor only 115
Sort 20 /U preprocessor option 117
View 20 undefine macros 117
Window 20 PREVIOUS debug command
page length of a listing 106 definition 257
PAM 5 producing
parameters *MODULE object 100
for the CRTPGM command 130 intermediate code file 101
used with compiler options 91 listing file 104
partner logical unit (LU) name of an AS/400 43 listing of struct and union variables 105
partner LU name of an AS/400 43 program
passing activation groups 188
binding command string to binder 122 add to debug session 216

Index 309
program (continued) project (continued)
and module authority 120 OS/400, creating 17
and service program objects 76 parts 6
binding to a non-existing service program 165 parts, locating 19
binding to a service program 141 setting up 17
calling 179 settings 6
changing optimization level 137 Smarts 6
containing circular references 159 target 6
creating in WorkFrame 24 target, designating 18
creating with unresolved references 158 Template 6
different from service program 141 views 6
dynamic program call, limits 72 Project Access Method 5
effect of debug data on size 259 Project Template
ending 188 definition 6
freeing resources 193 inheriting from 30
notes on running 179
on call stack 192
passing parameters 186 Q
preparing for debugging 258 /Q option 123
reducing size 138 /Q parameter 45
remove 217 QUAL debug command
removing observability 138 definition 257
running from AS/400 179 using 274
running from user-created CL command 183 querying existing connections 44
running in an activation group 191 .qwo file extension 61
running in the OPM default activation group 189
stepping into 270
stepping over 269 R
stepping through 268 RCLACTGRP CL command 189
stopping 188 RCLRSC command 193
updating 137 reading syntax diagrams xvi
viewing source while debugging 262 Reallocate Storage (CEECZST) bindable API 196
with unresolved import requests, example 159 reboot, what to do about connection 48
program entry procedure, defined 127 reclaiming
program object system resources 193
internal structure 128 recovering from reboot 48
purpose of changing 135 redirecting
program view window 232 messages with > 78
project output from preprocessor 116
creating 17 reducing object's size 138
customizing, in WorkFrame 19 referenced struct and union variables, listing 105
files, source directory 19 references
hierarchy 5 circular, in a program 159
Icon view 5 unresolved 158
in WorkFrame, defined 5 related publications
inheritance 6 AS/400 296
Monitor 6 BookManager 297
naming 17 OS/2 296
OS/2, actions 11 portability 296
OS/400, actions 12 VisualAge C++ for OS/2 295

310 IBM VisualAge C++ for OS/400 C++ User’s Guide


related publications (continued) scalar variables, changing value while debugging 286
VisualAge C++ for OS/400 295 scope of compiler options 93
removing search path
objects from a debug session 261 accumulate 69
observability 138 for externally described files 68
program 217 for precompiled header files 80
service program to debug session, example 262 header files 67, 102
removing breakpoints service program
about 264 adding to a debug session 261
all 268 backward-compatible changes 156
conditional 266 backward-compatible changes, example 166—170
unconditional breakpoints 264 binder language 152
renaming the CTTHCMD.EXE command file 47 binding to a program 141
replacing binding to modules 129
module object 99 changing 144
modules in a program 137 creating 141
reserved names 60 creating in WorkFrame 24
response file, compiling with 52 different from program 141
restarting example 145—150
debugger 240 example of removing from debug session 262
the current debug session 223 example ofadding to debug session 262
restoring export list, updating 156
defaults 224 export list, updating example 166—170
defaults, Call Stack window 246 non-existing, binding to a program 165
restrictions overview 141
precompiled header files 81 parameters for CRTSRVPGM command 142
when make file compares time stamps 174 reasons for using 141
return codes 78 reclaiming resources 193
RIGHT debug command related CL commands 145
definition 257 updating 144
Run menu 223 SET debug command
run-time definition 257
library, shared functions 194 setting
model 194 binder options in WorkFrame 24
storage, managing 195 breakpoints 211
running compiler options 89
a program from user-created command 183 compiler options in Build Smarts 22
preprocessor only, no compiling 115 compiler options in notebook 22
running a program 210 compiler options in WorkFrame 91
from AS/400 179 debug options 260
from user-created CL command 183 environment variables 64, 66
in named activation group, using *NEW 190 language level 70, 112
in the OPM default activation group 189 line breakpoint 220, 238
overview 179 setting breakpoints
about 264
conditional 266
S example 265, 267
/S file search option 112 unconditional breakpoints 264
SAVEPATH environment variable 62 Settings notebook
defined 4

Index 311
severity level of countable errors 109 starting (continued)
severity, compiler return codes 78 compiler 48
show debug server 202
module path 224 debugger from OS/2 205
show status line 224 ILE source-level debugger 260
/Si file search option 112 Startup Information window 206
simultaneous OS/2 and OS/400 compiles 57 statement view, creating 259
/Sn file search option 113 static procedure calls, purpose 128
sort components 224 static storage, limits 72
Sort Page 20 status line, show 224
sort threads 224 STEP debug command
source code definition 257
compiling into module objects 39 into 270
included in listing 107 into, example 271
included in listing file 104 over 269
language level, setting 70 step over 240
source file options stepping while debugging
parsing double-byte character sets 113 into a procedure 273
precompiled header files 112 into a program 270
purpose 112 into a program, example 271
/S file search option 112 over a procedure 273
setting language level 112 over a program 269
/Si file search option 112 through a program 268
size of enum variables 114 stopping a program 188
/Sn file search option 113 stopping the ILE source-level debugger 260
/Sp file search option 113 storage management
/Su file search option 114 allocating during run-time 196
source files containing double-byte character sets dynamic storage 195
(DBCSs) 113 managing run-time 195
source window colors 241 string option requiring escape sequence 91
/Sp file search option 113 string parameter in a compiler option 91
space pointers, displaying, sample source 290 strings used in a compiler option 91
specifying struct and union variables, listing 105
activation group 189 structure and union table in listing file 104
coded character set ID (CCSID) 121 structure, displaying, example 281
compiler options 89 structures and unions, packing and alignment 113
compiler options from ICCAS 90 /Su file search option 114
compiler options from OS/2 89 subtitle of listing 107
compiler options in WorkFrame 91 summary of compiler options 95
file search path 103 switches (+|-) in a compiler option 92
module and program authority 120 synchronizing
specifying an AS/400 connection name 43 system times with CTTTIME 174
specifying the partner LU name of an AS/400 43 workstation and host times, scope 175
SRCFILE parameter syntax check only 99
Start Debug (STRDBG) command syntax diagrams
Case (CASE) parameter 260 for commands, preprocessor directives, statements xvi
Update Production files (UPDPROD parameter) 260 for compiler options xviii
STARTCM command 40 how to read xvi
starting iccas command 50
Communication manager 40

312 IBM VisualAge C++ for OS/400 C++ User’s Guide


system union and struct
pointers, displaying sample source 290 listing of referenced variables 105
reclaiming storage 193 listing of variables 105
table in listing file 104
unions and structures, packing and alignment 113
T unresolved import requests
target changing program order 164
designating project 18 example 159—163
library for objects, designating 98 using *UNRSLVREF 163
V3R1 run-time environment 122 unresolved import, defined 158
template resolution, creating files for 101 unresolved references 158
Templates folder 21 *UNRSLVREF for unresolved import requests 163
restrictions with OS/400 applications 26 *UNRSLVREF option, usage 158
templates, displaying 285 unspecified char variables set to signed char 123
temporary files 63 UP debug command
terminating a program 188 definition 257
terminating the ILE source-level debugger 260 Update Program (UPDPGM) command, using 137
testing breakpoints 264 updating
conditional, setting and removing 266 a service program 144
unconditional, setting and removing 264 service program export list 156
text description of module object 122 service program export list, example 166—170
TFRCTL command 181 user and system #include files 106
threads pane 215 user entry procedure, defined 127
threads, sort 224 using the cooperative debugger 201
/Ti debugging option 108
time stamp
mismatch between host and workstation 174 V
precompiled header files 80 /V option 124
restrictions for make files 174 value of scalar variables, changing while debugging 286
title bar buttons 209, 224 value of variables and expressions, displaying 274
title of listing 107 variables
/Tl option 123 displayed as hexadecimal values, example 281
TMP environment variable 63 displaying while debugging 274
toggle at current line 238 displaying while debugging, example 275
Tools setup 6 duplicate names 134
TOP debug command equating a name during debugging 288
definition 257 information about, in listing file 104
Transfer Control CL command 181 size 72
types of file output 73 VDISK device driver 63
version string in the object and executable files 124
versions of C/400, compatibility with 71
U View Page 20
/U preprocessor option 117 viewing
unconditional breakpoint a different module while debugging 263
defined 264 source while debugging 262
setting and removing 264 virtual disk for TMP environment variable 63
setting, example 265 VisualAge C++ for OS/2
undefine macros during preprocessing 117 VisualAge C++ for OS/400
underscore character 60 using WorkFrame with 9

Index 313
VisualAge C++ for OS/400 debugger, introducing 201

W
/W debugging option 109
/Wgrp debugging options 109
Where is execution point 219, 234
wild card in file names 60
Window Page 20
work files 63, 77
WorkFrame
getting help 7
invoking CRTPGM from 132
invoking debugger from 207
invoking the binder 25
makemake, compiling from 49
setting compiler options 91
workstation
communication to AS/400 38
connecting to AS/400 41
disconnecting from AS/400 47
issuing CRTSRVPGM 143
multiple connections to AS/400 43
WRKACTJOB command 48
WRKCFGSTS command 79

X
/Xc file search option 103
/Xi file search option 103

314 IBM VisualAge C++ for OS/400 C++ User’s Guide

You might also like