AS400 C++ Users Guide
AS400 C++ Users Guide
Before using this information and the product it supports, be sure to read the general information under
“Notices” on page xiii.
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:
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.
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
Contents vii
Part 3. Binding and Running Your Program . . . . . . . . . . . . 125
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
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
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.
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.
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.
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.
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
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.
┌─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.)
.7/ .8/
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")
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.
This icon identifies examples that illustrate how to use a particular language feature
or other concept presented in the book.
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.
1 Introducing WorkFrame
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.
The contents of a typical OS/400 project called TEST are shown in Figure 2 on
page 4,
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.
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
how to take advantage of Project Smarts, and how to work with multiple Project
Access Methods (PAMs).
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
Guide for a complete discussion of how to customize projects, integrate your own
tools, and create projects from templates.
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
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.
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.
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
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.
See the VisualAge C++ for OS/2 User’s Guide for a description of the actions that
can be invoked for OS/2 objects.
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.
Select the Build action to build your project. You can choose between a normal build,
and rebuilding the entire project.
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.
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.
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
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.
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
See the VisualAge C++ for OS/2 User’s Guide for a description of the project-
creation methods.
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.
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
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.
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.
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.
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.
See the VisualAge C++ for OS/2 User’s Guide for a full description of the
VisualAge Editor.
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.
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.
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.
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.
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 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
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
See the VisualAge C++ for OS/2 User’s Guide for detailed information on the
various methods of loading browser files.
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.
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:
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.
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
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
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.
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.
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.
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
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.
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
6. Click on Add
7. Close the Tools setup window
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.
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.
iccas
AS/400
system
C++ Module Object
(*MODULE)
CRTPGM CRTSRVPGM
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.
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.
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)
55──CTTCONN──┬────────┬──┬──────────┬──────────────────────────5%
└─/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..
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.
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.
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.
55──CTTQCONN───────────────────────────────────────────────────5%
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.
55──CTTHCMD──┬──────────┬──┬────┬──┬──────────────┬────────────5%
└─/ASnname─┘ └─/Q─┘ └─as4ððcommand─┘
or
55──CTTHCMD──@response_file────────────────────────────────────5%
/ASnname
The /ASnname parameter is a user-defined name for the connection that you can use
to issue an AS/400 CL command.
/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.
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.
changes the current library on the AS/400 implied by the connection name myserver
to MYLIB.
is processed as
crtpgm abc actgrp(ag one)
'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.
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)
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.
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:
55──CTTEND─────────────────────────────────────────────────────5%
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.
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.
You must terminate the AS/400 connection explicitly through the Work With Active
Jobs (WRKACTJOB) command, from an AS/400 session.
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.
See “Compiling Source Files” on page 22 for details on how to set compiler
options and invoke the compiler from a WorkFrame project.
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
See Chapter 11, “Creating a Make File” on page 171 for details on writing your
own make file.
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
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
for each C++ source file. The intermediate file is not transferred to an AS/400 system
because there is no established connection.
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.
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.
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.
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.
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.
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
The INCLUDE environment variable is used when you compile source code for the
OS/2 platform through the icc compiler invocation command.
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.
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
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 (").
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.
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
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.
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
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,
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%;
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
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
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.
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.
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.
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-
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.
See “#include File Search Options” on page 102 for more information on the
compiler options /I, /Xc, and /Xi.
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.
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.
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:
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:
// 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 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.
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.
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 , };
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.
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
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 (.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
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-
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.
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.
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.
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.
See “Output File Management Options” on page 97 for more information on gen-
erating browser files.
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.
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.
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).
See “Debugging and Diagnostic Information Options” on page 108 for more
information on using the compiler options to control messages.
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.
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.
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"
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.
/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);
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.
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:
The best candidates for inlining are small functions that are called often.
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
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.
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
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.
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.
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
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.
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\".
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
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.
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.
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
/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
/ASr
Syntax Default
/ASr[+|-] /ASr+
/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.
/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.
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.
/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.
/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
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.
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.
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.
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.
/Xi
Syntax: Default:
/Xi[+|-] /Xi-
Use /Xi to stop the compiler from searching paths specified by the INCLUDE_ASV3R6
and INCLUDE_ASV3R1 environment variables.
If you specify any of the /Le, /Li, or /Lj options, you must also specify the /L,
/Lf, or /Ls option.
/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.
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.
/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.
/Le
Syntax: Default:
/Le[+|-] /Le-
/Lf
Syntax: Default:
/Lf[+|-] /Lf-
/Li
Syntax: Default:
/Li[+|-] /Li-
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
/Ls
Syntax: Default:
/Ls[+|-] /Ls-
/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.
/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.
/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.
/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.
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.
Recommendations:
If you use the /Ti option to generate debugger information, it is recommended that
you turn optimization off (/O-).
/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).
/Wgrp
Use /Wgrp to generate messages in the grp group. You can specify more than one
group.
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.
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
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.
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.
/Sn
Syntax: Default:
/Sn[+|-] /Sn-
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.
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.
Preprocessor Options
The options listed control the use of the preprocessor:
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.
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.
/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.
/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.
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.
Syntax: Default:
/U<name|> Retain macros.
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.
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.
/ASp
Syntax: Default:
/ASp[-|1|2a|2n|3a|3n] /ASp1
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.
/O
Syntax: Default:
/O[+|-|1ð|2ð|3ð|4ð] /O-
By default, the code is not optimized. /O- and /O1ð are equivalent.
/Oi
Syntax: Default:
/Oi[+|-] /Oi-
/Oivalue
By default, no user code is inlined. When /O[+|1|2] is specified, /Oi+ becomes the
default.
Other Options
Use the following options to control binder parameters, logo display, default char
type, and other IBM VisualAge C++ for OS/400 options:
Syntax: Default:
/? None
/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.
/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.
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.
/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.
/B
Syntax: Default:
/B"binding command" /B"crtpgm pgm(xxx/yyy) " with default
options of the CRTPGM host command
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.
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+
/Q
Syntax: Default:
/Q[+|-] /Q-
Use /Q+ to suppress the compiler logo that appears when you invoke the compiler.
/Tl
Syntax: Default:
/Tl[+|-|value] /Tl+
/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.
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 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.
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.
MYPROG(*PGM)
TRNSRPT Module
INCALC Module
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.
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.
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.
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.
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
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.
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)
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.
Note: If you also specify the /Q parameter, you do not see the generated informa-
tional messages.
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.
Use the *DUPPROC option on the CRTPGM OPTION parameter to allow duplicate pro-
cedure names.
See ILE Concepts, for further information on how to handle this situation.
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
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.
\ \ \ \ \ 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 \ \ \ \ \
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.
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.
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.
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.
See the CL Reference for more information on the CPROBJ and DCPOBJ com-
mands.
Creating a service program involves compiling source code into module objects and
binding one or more module objects into a service program object.
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.
See the CL Reference for a full description of the CRTSRVPGM command and
its parameters.
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.
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)
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.
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.
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.
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)
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
#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;}
#include "search.h"
// where.cpp
// contains definition of overloaded member function for class Search
#include "search.h"
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.
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.
// myprog.cpp
// Finds a character string in another character string.
#include <stdio.h>
#include <iostream.h>
#include <stdlib.h>
#include "search.h"
void main () {
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
SRVPGM SERVICE1
where() function
During the process of making MYPROG ready to run, the system verifies that:
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
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
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.
à@ ð
Display Module Information Display 3 of 3
Module . . . . . . . . . . . . : SEARCH
Library . . . . . . . . . . : MYLIB
Detail . . . . . . . . . . . . : \EXPORT
Module attribute . . . . . . . :
á ñ
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
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.
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.
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
55──RTVBNDSRC──┬───────────┬──Module──┬───────────┬─────────────5
└─Library1/─┘ └─Library2/─┘
5──┬────────────────────┬──┬──────────────────────┬─────────────5
└─Export source file─┘ └─Export source member─┘
5──┬──────────┬────────────────────────────────────────────────5%
├─\ADD─────┤
└─\REPLACE─┘
For detailed information on the RTVBNDSRC command and its parameters enter
RTVBNDSRC on an AS/400 command line and press F1 for Help.
Member ONE in file MYLIB/QSRVSRC now contains the following binder language:
à@ ð
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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
á ñ
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.
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.
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.
name->Kind() == MemberFunction
((MemberFunctionName \) name)->Scope()->Text() is "X"
((MemberFunctionName \) name)->RootName() is "f"
((MemberFunctionName \) name)->Text() is "X::f(int)"
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.
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.
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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
á ñ
PGM A
main()
SRVPGM SP1
func1()
SRVPGM SP2
func2()
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 = ð;
// 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:
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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
á ñ
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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
á ñ
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.
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.
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.
à@ ð
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 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
á ñ
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:
//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
// 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.
Program Description
The figure below shows the exports in the existing version of service program COST,
and in the updated version.
The figure below shows the import requests in the existing program COSTDPT1, and in
the new program 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 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
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
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> 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;
// 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;
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
Run program COSTDPT2 from an OS/400 command line using the CL command CALL
COSTDPT2.
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
See the VisualAge C++ for OS/2 User’s Guide, for information on creating make
files using the MakeMake utility.
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.
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.
//Description block
target: dependencies
command
Example:
Note: $(drive) must be replaced with the mounted drive that shadows your AS/400
libraries and files on the OS/2 workstation.
If a dependency list is very long, you may have to split lines using a backslash (\), as
shown in the following example:
$(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.
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.
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.
55──CTTTIME──┬──────────┬──┬─────────┬─────────────────────────5%
└─/ASnname─┘ └─[SYNCH]─┘
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.
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.
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:BB.MODULE: bb.cpp
iccas -q -c bb.cpp
END:
cttdis // ends the connection established earlier
// 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;
}
To create program AA., invoke the make file by entering nmake aa.mak on an OS/2
command line.
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.
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.
55──CALL PGM──(library-name/program-name)──────────────────────5%
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).
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 │
└───────────────┘ └───────────────┘
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.
PGM PARM(&STRING)
DCL VAR(&STRING) TYPE(\CHAR) LEN(2ð)
DCL VAR(&NULL) TYPE(\CHAR) LEN(1) VALUE(X'ðð')
DSPJOBLOG
ENDPGM
// xrun2.cpp
// Source for Program XRUN2
// Receives and prints a null-terminated character string
#include <iostream.h>
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.
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.
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 │
└────────────────────────────┘
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>
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ððð
à@ ð
It costs $11385.ðð to buy 5ððð HAMMERS
Press ENTER to end terminal session.
>
á ñ
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>
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
Note: These changes only apply when you call a program from a command line, not
to interlanguage calls.
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.
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.
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.
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
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
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
To create these programs into the same activation group, you specify GROUP1 on the
ACTGRP parameter when you create each program:
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
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
By default, each program is created into a different activation group, identified by the
ACTGRP parameter (*NEW).
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
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
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.)
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.
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).
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.
See CL Reference for more information on the RCLRSC command. See ILE
Concepts for more information on the RCLRSC and activation groups.
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.
In the default activation groups, I/O files are not automatically closed. The I/O
buffers are not flushed unless explicitly requested.
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.
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.
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.
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.
See the System API Reference for specific information about the storage-
management bindable APIs.
The following examples illustrate dynamic storage allocation with new and delete:
1. Dynamic allocation and de-allocation of storage for a class 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:
...
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[].
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
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.
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.
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.
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.
Chapter 13. Using the IBM VisualAge C++ for OS/400 Debugger 203
Preparing for Debugging
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 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;
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.
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:
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.
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.
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
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.
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.
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.
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.
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.
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.
See “Breakpoints Menu Choices” on page 219 for more information on break-
points.
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.
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
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
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
Add Program...
Displays the Add Program window, which allows you to add a new program to the
list of programs being debugged.
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.
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.
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.
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.
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.
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.
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.
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.
The first two choices listed under the Monitors menu are also accessible from
buttons in the title bars of the program view windows.
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
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.
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.
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.
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.
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.
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.
Monitor properties...
Displays the Monitor Properties window, which allows you to select the settings for
monitoring variables or expressions.
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.
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.
Select the appropriate radio button for the data type you want.
Select the appropriate push button to continue.
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.
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.
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
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.
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.
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.
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.
.
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.
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.
Select include...
Displays the Select Include window, which allows you to view the files that are
included in your program.
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.
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.
*TEXT
Displays the *TEXT view.
*LISTING
Displays the *LISTING view.
*STATEMENT
Displays the *STATEMENT view.
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.
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.
For more information on the Breakpoint List window, refer to “Using the Break-
points List Window” on page 250.
Delete all
Deletes all the breakpoints that have been set.
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.
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.
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
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.
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.
The Run to location choice stops only on runnable lines. If a highlighted line is not
runnable, the run is not performed.
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.
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
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.
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.
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
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.
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.
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.
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.
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.
Delete
Select the Delete choice to delete variables or expressions that are being monitored
from a monitor window.
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.
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.
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
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.
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.
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-
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.
Delete
Deletes the highlighted breakpoints in the window.
To delete a breakpoint:
Disable/Enable
Disables the highlighted breakpoint if it is enabled, or enables the highlighted break-
point if it is disabled.
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.
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.
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.
Sort...
Displays the Sort Breakpoints window, which allows you to sort the breakpoints by
the characteristics of the breakpoint.
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.
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
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
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.
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.
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
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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".
The module name is shown. The module must exist in a program that has been added
to the debug session.
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.
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.
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.
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.
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.
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.
At this point, you can evaluate fields, set more breakpoints, and run any of the debug
commands.
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.
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.
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.
on the debug command line. The breakpoints are removed from all of the modules
bound to the program.
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.
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
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.
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.
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.
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.
Bottom
Debug . . .
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:
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.
The scope of the variables used in the EVAL debug command is defined by using the
QUAL debug command.
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.
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.
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.
Pointers
/\ Display a pointer \/
>eval pc1
pc1 = SPP:ððððCð26ð9ðð1ð7C
/\ Dereference a pointer \/
>eval \pc1
\pc1 = 'C'
/\ Casting a pointer \/
>eval \(short \)pc1
\(short \)pc1 = -15616
Figure 61 (Part 1 of 2). Sample EVAL Commands for C Pointers, Variables, and Bit Fields
Simple Variables
/\ Implicit conversion \/
>eval u1 = -1ð
u1 = -1ð = 4294967286
/\ Implicit conversion \/
>eval (int)u1
(int)u1 = -1ð
Bit Fields
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.
Enumerations
/\ Assign by number \/
>eval Number = 1
Number = 1 = two (1)
/\ Assign by enumeration \/
>eval Number = three
Number = three = three (2)
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.
/\ 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.
Figure 65 shows the entire structure with two elements being displayed. Each
element of the structure is formatted according to its type and displayed.
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.
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.
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.
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.
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.
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 }
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.
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
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:
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.
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.
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.
#include <iostream.h>
#include <pointer.h>
union u{ // Union
int x;
unsigned y;
};
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
}
#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
errorCode.BytesProvided = ð;
CreateUserSpace("QTEUSERSPCQTEMP ",
"QTESSPC ",
1ð,
ð,
"\ALL ",
" ",
"\YES ",
&errorCode
);
return ð;
}
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;
};
class outter {
public:
static int static_i;
void funct();
} inobj;
};
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
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
}
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
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
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
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
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
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
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
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
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