Welcome to the July, 1996 Issue of the C/370 Newsletter

IBM Corp 1996

                  370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
             370 370 370 370 370 370 370 370 370 370 370 370 370
             370 370 370 370 370 370 370 370 370 370 370 370
                  370 370 370 370 370 370 370 370 370 370

C/370(*) Compiler News

July 1996 Volume 4 Number 3


Table of Contents

Welcome to the July, 1996 Issue of the C/370 Newsletter

  • In This Issue
  • A new C Compiler for VSE
    C Set++ for the Solaris Operating System
  • High Performance C and C++ Compilers
  • IBM Open Class
  • And more class libraries
  • Two Powerful Debuggers...
  • Browser Gives You Multiple Views
  • Test Coverage Analyzer (tcov)
  • Helpful Documentation - Online or On the Page
  • Standards Compliance
  • Join the VisualAge C++ Family
  • Using the Interactive System Productivity Facility (ISPF)
  • IBM C/C++ WEB Information
  • You ask, we answer
    A word from your editor
    Coming Soon
  • C/370 Compiler News Volume 4 Number 3 July/96 Issue
  • Reader's Comment Form

  • Welcome to the July, 1996 Issue of the C/370 Newsletter

    In This Issue

    ( )

    A new C Compiler for VSE

    On April 23, 1996, in the Announcement letter for VSE/ESA(*) Version 2 Release 2, IBM(*) made the following Statement of Direction.

    " IBM intends to provide a C Language compiler for VSE/ESA Version 2 Release 2 or later and VSE/ESA Version 1 Release 4 based on Language Environment(*) technology. The future VSE C Language compiler will support 31-bit addressing and be Year 2000-ready. It is intended to eventually replace the existing C/370 compiler in the VSE environment."

    For those of you who use our existing C compiler on VSE, this should be good news and we will have an article in a future newsletter giving you more details.


    C Set++ for the Solaris Operating System

    The C Set++ for Solaris development environment extends your programming reach. From NT(**) to OS/2(*) to AIX(*) and now to the Solaris operating system. Fast and easy code portability without compatibility problems.

    This comprehensive C++ development environment includes IBM Open Class(*), a cross-platform standard in class libraries. You have the flexibility of a consistent programming interface across many platforms: Windows(**) NT, Windows 95, OS/2 Warp(*), AIX, Sun(**) Solaris, MVS(*), OS/400(*)... and more to come.

    High Performance C and C++ Compilers

    The C Set++ for Solaris compilers generate highly optimized code to exploit Sun SPARCstation(**) architecture.

    The C and C++ compilers give you:

    C Set++ for the Solaris Operating System supports the latest features of the C++ language, such as templates and exception handling. Use the templates to define generic functions and classes. When an exception occurs, you can transfer control to a predetermined point in the program.

    IBM Open Class

    : A Complete Set of Class Libraries.

    IBM Open Class is a set of C++ class libraries that gives you an extensive choice of building blocks for creating your applications. You reduce your development time by using the available functions or by tailoring the classes to suit specific applications.

    You can program at a high level of abstraction in the early stages of the development cycle. Then, in later stages, replace any abstract types with the appropriate concrete implementation.

    And more class libraries

    1. The Application Support Class Library: Contains classes that support string manipulation, date-and-time calculations, and exception handling.

    2. The I/O Stream Library: Supports formatted Input/Output in C++.

    3. The Complex Mathematics Library: You can easily manipulate complex numbers and perform standard mathematical operations.

    4. The Task Library: You can write programs with routines that appear to run in parallel. This simulated multitasking means that routines can communicate with each other and start new tasks.

    Two Powerful Debuggers...

    The C Set++ for Solaris development environment comes with two debuggers. You use xldb to debug C and C++ programs. HeapView helps you manage heap storage.

    For Coding Errors

    xldb, the new graphical debugger tool, makes debugging C and C++ programs simpler and more efficient. You can easily see and correct coding errors. This debugger also comes with C Set++ for AIX. Consistent tools across platforms mean easier application development and a shorter learning curve.

    And for Detecting Memory Errors

    Because of their dynamic nature, memory-corruption problems are difficult to debug. Use this tool to detect and analyze problems caused by allocation and deallocation of memory, and to prevent costly memory-corruption problems.

    Browser Gives You Multiple Views

    Use the browser as a static analysis tool after you have compiled your program. A full-function browser for C and C++ programs, it complements the compilers. It's extremely helpful when you are looking at unfamiliar code. For example, you can quickly see the inheritance relationships among classes or a list of all the root classes.

    The browser is based on client/server architecture. The server contains information on classes, functions and files. From anywhere on the network, you can use the client to query this information.

    You have multiple views in a single window

    1. A list view shows you the names of the program entities, such as directories, files, classes, functions, and variables.

    2. A graph view displays graphical representations of relations in the source code structures, such as the class hierarchy and the functions call graph.

    3. A text view contains the textual representation of the structure as it appears in the source file.

    Test Coverage Analyzer (tcov)

    Tells you how often a line of code is executed. You can quickly identify untested areas in your program or potential bottlenecks.

    Helpful Documentation - Online or On the Page

    Accurate and easy-to-use hardcopy and softcopy information help you get the most out of the compiler and tools. An online tutorial shows you what you want to know - from the basics of object-oriented programming to advanced template usage. And lots of examples to use as models.

    Standards Compliance

    C Set++ for the Solaris Operating System supports:

    Join the VisualAge C++ Family

    IBM C Set++ for the Solaris Operating System is part of the IBM family of VisualAge C++ products. Its consistent set of tools and class libraries across many platforms makes you a more productive programmer. You'll rediscover the reasons you became a programmer - creating new applications - without wasting time entangled in unnecessary complexity.

    For more information about IBM C Set++ for the Solaris Operating System, please contact your IBM Marketing Representative or visit us on the World Wide Web. Look for http://www.software.ibm.com/ad/cset/csetsolaris/csetsolaris.html


    Using the Interactive System Productivity Facility (ISPF)

    C/C++ for MVS allows access to the Interactive System Productivity Facility (ISPF) Dialog Management Services. Some of the services provided by ISPF include:

    For C applications, the interface routine for ISPF is called ISPLINK. Because ISPF uses OS style linkage, calls from C to ISPF require this pragma:

          #pragma linkage(ISPLINK, OS)
    

    For C++ applications, two interfaces may be used with ISPF: ISPLINK and ISPEXEC. Because ISPF uses OS style linkage, calls from C++ to ISPF require that ISPLINK and ISPEXEC be prototyped as extern "OS", as follows

          extern "OS"{
            int ISPLINK(char*,...);
          }
    
          extern "OS"{
            int ISPEXEC(int, char*,...);
          }
    
    

    Consult the ISPF manuals for specific information about using the ISPF Dialog Management Services.

    To run the following example under C:

    1. Compile and link the CBC3GIS3 C source file using the EDCCL procedure. Override the SYSLIB DD statement on the LKED step to use the ISPF load library available on your system. Your JCL should appear similar to the fragment below:
                //CISPF     EXEC EDCCL,
                //          INFILE='userid.c(CBC3GIS3)',
                //          OUTFILE='userid.loadlib(CBC3GIS3),DISP=SHR'
                //LKED.SYSLIB  DD DSN=CEE.V1R5M0.SCEERUN,DISP=SHR
                //             DD DSN=ispf.loadlib,DISP=SHR
                //LKED.SYSIN  DD DATA,DLM='/>'
                 NAME CBC3GIS3(R)
                />
      

    2. Copy the CBC3GIS2 and CBC3GIS4 menus, and the CBC3GIS5 panel to your own ISPPLIB data set. Copy CBC3GIS1 to your own CLIST data set.

    3. Ensure that your ISPPLIB data set is allocated to the ISPPLIB ddname. The data set containing the CBC3GIS3 load module, and the SCEERUN data set, should be allocated to the STEPLIB ddname.

    4. Run the CLIST. The opening menu of the example will be displayed. Choose the first option to call the program that starts the C to ISPF interface and displays a secondary menu. You can either exit from this menu or press the help key for a help panel.

    
        CBC3GIS1
    
    
          /* THIS CLIST STARTS THE ISPF EXAMPLE */
    
          ISPEXEC SELECT PANEL(CBC3GIS2)
    
    


    
        CBC3GIS2
    
    
          )ATTR DEFAULT(%+_)
          /* this menu is used by the ISPF example */
                /*  % TYPE(TEXT) INTENS(HIGH)      defaults displayed for
                /*  + TYPE(TEXT) INTENS(LOW)       information only
    
          )BODY
          %---------------------  SAMPLE ISPF DIALOG  PANEL  ----------------
          %OPTION ===>_ZCMD
          +
          +  %1+ SELECTION 1      CALL C PROGRAM.
             %2+ FUTURE           NOT IMPLEMENTED.
             %3+ FUTURE           NOT IMPLEMENTED.
          +
          +ENTER %END+COMMAND TO TERMINATE.
          )PROC
             &ZSEL=TRANS(TRUNC(&ZCMD,'.')
                       1,'PGM(CBC3GIS3)'
                       *,'?')
          )END
    


    
        CBC3GIS3
    
          /* this program shows how to use ISPF with C */
    
          #include <stdio.h>
          #include <stdlib.h>
    
          #pragma linkage(ISPLINK,OS)
    
          extern ISPLINK() ;
    
          int rc,buflen;
          char buffer[20];
    
          int main(void)
          {
          /* Retrieve the panel definition CBC3GIS4 and display it. */
    
             strcpy(buffer,"PANEL(CBC3GIS4)");
             buflen = strlen(buffer);
             rc = ISPLINK("SELECT", buflen, buffer);
          }
    


    
        CBC3GIS4
    
          )ATTR DEFAULT(%+_)
          /* this menu is used by the ISPF example */
                /*  % TYPE(TEXT) INTENS(HIGH)      defaults displayed for
                /*  + TYPE(TEXT) INTENS(LOW)       information only*/
                /*  _ TYPE(INPUT) INTENS(HIGH) CAPS(ON) JUST(LEFT)
          )BODY
          %------------------------  A SAMPLE ISPF MENU ---------------------
          %OPTION ===>_ZCMD
          +
          +  %1+ SELECTION 1      NOT IMPLEMENTED.
             %2+ SELECTION 2      EXIT
    
          +   %END+ TO EXIT.
          +
          )INIT
            .HELP = cbc3gis5
          )PROC
             &ZSEL=TRANS(TRUNC(&ZCMD,'.')
                   2,'EXIT'
                   *,'?')
          )END
    


    
        CBC3GIS5
    
          )ATTR DEFAULT(%+_)
          /* this panel is used by the ISPF example */
          )BODY
          %---------------------  Sample ISPF Help Panel  -------------------
          +
             This is a HELP panel.  Enter %END +to exit.
    
          )PROC
          )END
    

    To run the following example under C++:

    1. Compile, prelink and link the C++ source file using the CBCCL procedure. You can use either the ISPLINK version of the code (CBC3GIS8) or the ISPEXEC version of the code (CBC3GISB). Override the SYSLIB DD statement on the LKED step to use the ISPF load library available on your system. Your JCL should appear similar to the fragment below:
                //CXXISPF   EXEC CBCCL,
                //          INFILE='userid.c(CBC3GIS8)',
                //          OUTFILE='userid.loadlib(CBC3GIS8),DISP=SHR'
                //LKED.SYSLIB  DD DSN=CEE.V1R5M0.SCEELKED,DISP=SHR
                //             DD DSN=ispf.loadlib,DISP=SHR
                //LKED.SYSIN  DD DATA,DLM='/>'
                 NAME CBC3GIS8(R)
                />
      

    2. Copy the CBC3GIS7 menu (if you are using ISPLINK) or the CBC3GISA menu (if you are using ISPEXEC) to your own ISPPLIB data set. Copy the CBC3GIS4 menu and CBC3GIS5 panel to your ISPPLIB data set as well. Copy the CBC3GIS6 CLIST (if you are using ISPLINK) or the CBC3GIS9 CLIST (if you are using ISPEXEC) to your own CLIST data set.

    3. Ensure that your ISPPLIB data set is allocated to the ISPPLIB ddname. The data set containing the CBC3GIS8 or CBC3GISB load module, and the SCEERUN data set, should be allocated to the STEPLIB ddname.

    4. Run the CLIST. The opening menu of the example will be displayed. Choose the first option to call the program that starts the C++ to ISPF interface and displays a secondary menu. You can either exit from this menu or press the help key for a help panel.

    
        CBC3GIS6
    
    
          /* THIS CLIST STARTS THE ISPF EXAMPLE */
    
          ISPEXEC SELECT PANEL(CBC3GIS7)
    


    
        CBC3GIS7
    
    
          )ATTR DEFAULT(%+_)
          /* this menu is used by the ISPF example */
                /*  % TYPE(TEXT) INTENS(HIGH)      defaults displayed for
                /*  + TYPE(TEXT) INTENS(LOW)       information only
    
          )BODY
          %---------------------  SAMPLE ISPF DIALOG  PANEL  ----------------
          %OPTION ===>_ZCMD
          +
          +  %1+ SELECTION 1      CALL C PROGRAM.
             %2+ FUTURE           NOT IMPLEMENTED.
             %3+ FUTURE           NOT IMPLEMENTED.
          +
          +ENTER %END+COMMAND TO TERMINATE.
          )PROC
             &ZSEL=TRANS(TRUNC(&ZCMD,'.')
                       1,'PGM(CBC3GIS8)'
                       *,'?')
          )END
    


    
        CBC3GIS8
    
          /* this program shows how to use ISPF with C++, using ISPLINK */
    
          #include <stdlib.h>
          #include <stdio.h>
          #include <string.h>
    
          extern "OS" {
             int ISPLINK(char*,...);
          }
    
          int rc,buflen;
          char buffer[20];
    
          int main(void)
          {
          /* Retrieve the panel definition CBC3GIS4 and display it. */
    
             strcpy(buffer,"PANEL(CBC3GIS4)");
             buflen = strlen(buffer);
             rc = ISPLINK("SELECT",buflen, buffer);
          }
    


    
        CBC3GIS9
    
    
          /* THIS CLIST STARTS THE ISPF EXAMPLE */
    
          ISPEXEC SELECT PANEL(CBC3GISA)
    


    
        CBC3GISA
    
    
          )ATTR DEFAULT(%+_)
          /* this menu is used by the ISPF example */
                /*  % TYPE(TEXT) INTENS(HIGH)      defaults displayed for
                /*  + TYPE(TEXT) INTENS(LOW)       information only
    
          )BODY
          %---------------------  SAMPLE ISPF DIALOG  PANEL  ----------------
          %OPTION ===>_ZCMD
          +
          +  %1+ SELECTION 1      CALL C PROGRAM.
             %2+ FUTURE           NOT IMPLEMENTED.
             %3+ FUTURE           NOT IMPLEMENTED.
          +
          +ENTER %END+COMMAND TO TERMINATE.
          )PROC
             &ZSEL=TRANS(TRUNC(&ZCMD,'.')
                       1,'PGM(CBC3GISB)'
                       *,'?')
          )END
    


    
        CBC3GISB
    
          /* this program shows how to use ISPF with C++, using ISPEXEC */
    
          #include <stdlib.h>
          #include <stdio.h>
          #include <string.h>
    
          extern "OS" {
             int ISPEXEC(int, char*);
          }
    
          int rc,buflen;
          char buffer 20 ;
    
          int main(void)
          {
          /* Retrieve the panel definition CBC3GIS4 and display it. */
    
             strcpy(buffer,"SELECT PANEL(CBC3GIS4)");
             buflen = strlen(buffer);
             rc = ISPEXEC(buflen, buffer);
          }
    


    
        CBC3GIS4
    
    
          )ATTR DEFAULT(%+_)
          /* this menu is used by the ISPF example */
                /*  % TYPE(TEXT) INTENS(HIGH)      defaults displayed for
                /*  + TYPE(TEXT) INTENS(LOW)       information only*/
                /*  _ TYPE(INPUT) INTENS(HIGH) CAPS(ON) JUST(LEFT)
          )BODY
          %------------------------  A SAMPLE ISPF MENU ---------------------
          %OPTION ===>_ZCMD
          +
          +  %1+ SELECTION 1      NOT IMPLEMENTED.
             %2+ SELECTION 2      EXIT
    
          +   %END+ TO EXIT.
          +
          )INIT
            .HELP = cbc3gis5
          )PROC
             &ZSEL=TRANS(TRUNC(&ZCMD,'.')
                   2,'EXIT'
                   *,'?')
          )END
    


    
        CBC3GIS5
    
          )ATTR DEFAULT(%+_)
          /* this panel is used by the ISPF example */
          )BODY
          %---------------------  Sample ISPF Help Panel  -------------------
          +
             This is a HELP panel.  Enter %END +to exit.
    
          )PROC
          )END
    

    IBM C/C++ WEB Information

    IBM has put a great deal of information onto the World Wide Web for application developers. Below are some pointers to information that could be useful to C/C++ developers on all platforms. If you want to find out more, Start at the IBM Software Home Page at

        http://www.software.ibm.com/index.html
    
    and surf from there or you can go directly to the URLs below.

    Key Home Pages

     IBM VisualAge for C++ and C/C++ Family Information
        http://www.software.ibm.com/ad/visualage_c++/
    
     IBM Open Class
        http://www.software.ibm.com/ad/visualage_c++/csetos2/opencl.html
    

    Technical Papers & Information

     IBM C++ Family Overview
        http://www.software.ibm.com/ad/visualage_c++/csetos2/wp1-fam.html
    
     Object Oriented Programming with VisualAge for C++
        http://www.software.ibm.com/ad/visualage_c++/csetos2/wp3-obj.html
    
     VisualAge for C++ - Open Class Library
        http://www.software.ibm.com/ad/visualage_c++/csetos2/wp4-ope.html
    
     Visual Construction from Parts with VisualAge for C++
        http://www.software.ibm.com/ad/visualage_c++/csetos2/parts.html
    
     C and C++ Porting Tips
        http://www.software.ibm.com/ad/visualage_c++/csporttip.html
    
     C/C++ FAQs
        http://www.software.ibm.com/ad/cset/os2/dde4faq.html
    
    

    Other Important Information

     VisualAge for C++ for OS/2 Distributed Application Development Toolkit
        http://www.software.ibm.com/ad/visualage_c++/distadt/index.html
    
     IBM TeamConnection
        http://www.software.ibm.com/software/ad/teamcon/tcprdsum.htm
    
     IBM ObjectConnection
        http://www.software.ibm.com/software/ad/visage/varc/varcocp.htm
    
     IBM Object Technology Certification
        http://www.software.ibm.com/spslibrary/
    
     IBM Developers Connection
        http://www.developer.ibm.com/sdp/DevCon/
    
     Books on C/C++
        http://www.software.ibm.com/ad/cset/books.html
    
     Education
        http://www.software.ibm.com/ad/cset/educate.html
    
     C/C++ Other Links and Newsgroups
        http://www.software.ibm.com/ad/cset/links.html
    
     C/C++ Services
        http://www.software.ibm.com/ad/cset/services.html
    
     Download Library, Fixes, Product Demostrations and Free Software
        http://www.software.ibm.com/download
    
     IBM Software Quarterly Magazine
        http://www.software.ibm.com/sq
    

    The Internet also has a number of newsgroups that vary dramatically in content and relevance but may give you additional information on C/C++ that you never thought you could get.

    1. COMP.LANG.C has a lot of discussion on C for PCs, but it also has a number of pointers to books and sites that have shareware code. COMP.LANG.C++ is a similar newsgroup, but topics are more C++ oriented. Be aware that both of these are very busy newsgroups.

    2. COMP.STD.C has a lot of discussion on C standards and compiler behavior regarding standards and portability. Again, COMP.STD.C++ is a similar newsgroup with a more C++ orientation.

    3. C370-L@CMUVM.CSE.CMICH.EDU is more oriented towards C on the S/370(*) mainframes. This particular discussion group is monitored by C/370 development who will frequently answer the questions. To join this discussion group, send a note to LISTSERV@CMUVM.CSV.CMICH.EDU with the following contained in the note.
          subscribe C370-l your_full_name
      

    You ask, we answer

    These questions are culled from a variety of sources: from various question and answer databases, from customer calls, and from our own experiences. If you have a question you'd like answered, please send it to IBMMAIL(CAIBMRXZ) or inetc370@vnet.ibm.com. We'll answer your question and perhaps print your question and answer in the next newsletter.

    Question - fopen returns data set not found

    Two data sets are passed as parms to TORCCSID, an AD/Cycle(*) 1.2 MVS C program.

      //RUN   EXEC PGM=TORCCSID,REGION=1024K,COND=EVEN,
         PARM='TAYLORP.CDRA.FINAL.TTB(CCSID) TAYLORP.CDRA.FINAL.TORORSCS'
    

    Failing code segment:

      (*ScanFTXT)->FileHandle = fopen(Filename,"r");
      if ((*ScanFTXT)->FileHandle == NULL) ??<
          printf("SCANFTXT: %s (%d)\n",strerror(errno),errno);
    

    fprint shows:

      SCANFTXT: EDC5049I The specified file name could not be located (49)
      TORCCSID: Could not open TextFile TAYLORP.CDRA.FINAL.TTB(CCSID)
    

    I have verified the DS exists (with contents) and have tried another dsname with same results. Verified MVS DS is cataloged and correct spelling.

    I believe the printf shows that the filename is null terminated and do not believe that the DSN needs to be passed with quotes. Any other ideas?

    Answer

    It looks like it is related to single quotes. Single quotes are used to distinguish fully-qualified DSNs from non-fully-qualified DSNs. If you pass a non-fully-qualified DSN to fopen(), it pre-pends the current high-level qualifier or TSO prefix. Your fopen() is probably failing because it can't find 'prefix.TAYLORP.CDRA.FINAL.TTB(CCSID)'.

    You can either:

    //RUN   EXEC PGM=TORCCSID,REGION=1024K,COND=EVEN,
    // PARM='''TAYLORP.CDRA.FINAL.TTB(CCSID)'' ''TAYLORP.CDRA.FINAL.TORORSC
    //             S'''
    

    Question - Spurious CHECKOUT warning

    The following code snippet produces a spurious CHECKOUT warning:

        1       |unsigned char rc = 0;
        2       |unsigned char f1(void);
        3       |
        4       |void f2(void)
        5       |{
        6     1 |    rc = f1();
    ===========> ....b..a.c.......................................
    *=WARNING=======> a-EDC0817 Type conversion may result in lost
                        precision.
    *=INFORMATIONAL=> b-EDC0140 Operand has type unsigned
                        character.
    *=INFORMATIONAL=> c-EDC0140 Operand has type signed integer.
        7       |}
    
    
    The cross reference knows that f1() returns an unsigned char:
    
    f1     2-0:2    Class = external definition,
                    Type = C function returning unsigned character
                    6-0:6
    

    Answer

    When a C compiler returns an unwidened type, it needs to widen it, just in case a programmer calls the function without prototyping it. In this case, the 'char' being returned is widened to 'signed int'. The compiler unfortunately has lost the information that this was, just a little while ago, a char and now sees it as an int. If the function truly did return an int, then the message would be valid, so the compiler has to be smarter and see through the widening it is doing.

    If you examine the ANSI library, you'll note that all ANSI functions that could return a char don't - they return an int. That's to ensure programmer's code works (since the default return type for an unprototyped function is 'int').

    So, the checkout message is still wrong, but if the routine in question might be used by other programmers, you may want to consider returning an 'int' instead of 'char' to avoid potential problems. In addition, you might get better code generated since the compiler won't be doing unnecessary widening/flattening from char/int/char for the function call.

    Question - FOPEN fails

    User A is browsing or editing (no matter which one) a member of a PDS data set via ISPF. If another user is running a C/370 program with a FOPEN for a different member, but on the same data set as user A is already working, then this FOPEN gives a null pointer return value. Two examples of the FOPEN are

       if ( (p_f2 = fopen(filename2, write_bin_mode)) == NULL)
       {(void) sprintf(Meldung, ERR_MESSAGE_38, filename2);
       return(ERROR); }
    
       if ( (p_f2 = fopen(filename2, "wb,type=record")) == NULL)
       {(void) sprintf(Meldung, ERR_MESSAGE_38, filename2);
       return(ERROR); }
    
    where filename2 is 'XAES001.TSO.CNTL(SA45)', for example.

    It seems that the C/370 FOPEN requires a exclusive open for the data set and not only for the member. Is this how it should work?

    Answer

    C/370 fopen() will dynamically allocate the dataset with DISP=OLD for write-modes. The reason is that if more than one task writes to the same dataset with DISP=SHR allocations, the data may be unpredictably corrupted. The same thing is also true for PDS members, because even if two different members are being updated/written, physically it is the same dataset, and the data corruption will result from concurrent update tasks. Please note that 'fopen("dd:PDS(member)","wb")' will NOT solve the problem either.

    Question - C/370 books

    Do you know of any books that can help me learn C/370 on the mainframe?

    Answer

    You might want to take a look at

     C Programming in the MVS Environment
    
     V. Mitra Gopaul Walter Falby
    
     VNR Computer Library
     VAN NOSTRAND REINHOLD New York
    
     Copyright 1992 ISBM 0-442-00628-4
    

    Question - QSAM access method

    I'm trying to get my C/370 routine running under MVS to use QSAM as the underlying access method when performing file I/O. The file is a fixed blocked binary file with LRECL=BLOCKSIZE=10240. When I open such a file with access mode = rb and perform a STROBE(**) on the program execution, it tells me that the access method is BSAM. I've also experimented with the "type=record" and "noseek" file open parameters which also resulted in BSAM as the access method.

    What do I have to do to get it to use QSAM instead of BSAM? Our understanding is that QSAM is much faster than BSAM when performing sequential reading writing of blocks.

    Answer

    You don't say what release of C/370 or LE/370 library that you are using.

    If you are using C/370 v2.1 or LE/370 v1.2 or older versions then you only get BSAM. With C/370 v2.2 or LE/370 v1.3 or later releases you can specify NOSEEK and read-only or write-only mode (r, rb, w, wb, a, ab) to get QSAM. This information is explained in the Programmer Guide manuals of the said releases.

    Question - main returning int vs. long

    We are currently porting our application to MVS. While using the C/C++ for MVS compiler, we are running into problems when trying to return a LONG INT from MAIN. For some reason they only appear to be able to return a VOID or an INT. The message even seems to indicate that they can only return a VOID or INT.

    Is this a known restriction? If not, is there a fix for this (or a workaround)? Thanks in advance for your help with this.

    Answer

    The compiler is enforcing ANSI behaviour - ANSI states that you can only return an int or void from main. For MVS, it doesn't matter since a 'long' and an 'int' are both 32 bits - the ANSI statement is for portability to machines where longs and ints aren't the same size (some environments have a long as 32 bits and an int as 16 bits)

    Question - HWOPTS option

    In "C/C++ for MVS User's guide", the HWOPTS option is described as "HWOPTS(string)". What does "string" mean? Is it O.K. to specify "string" in lowercase or do I have to set another string from my C program?

    Answer

    "hwopts(string)" option tells the compiler to generate more optimized code to process strings for processors which have the Logical String Assist Feature.

    Question - C/C++ instructions that multiply 2 32 bit

    Does the C/C++ for MVS V3r1.1 have an instruction(s) which will allow to multiply a 32-bit integer by a 32-bit integer and return a single 64 bit integer.

    Answer

    C/C++ for MVS does not support a 64-bit integer.

    Question - C++ messages from C compile/no C functions in DLL

    I am porting the SOMBank application (ITSC Redbook sample) to MVS using nothing but OpenEdition(*). The application is a SOM application written entirely in C. The fully built application is packaged as a couple of executables for line mode user interfaces, and a bunch of DLLs.

    After playing around with the Makefile to call the c89 compiler and pass the -W c,dll option to compile all the C as dll enabled, and linking with -W l,dll to build the DLLs (I left this off for the base executables), I see some interesting results.

    1. During the make, several of the C compiles put out this message
      WARNING CBC3517 SYS1.SGOSH.H(SOMDEXT):58
      Option system for #pragma is not supported.
      
      I found it interesting that my C compile put out CBC warnings.

    2. When I try to run the executables, I get this message
      EDC6060S The DLL that you are attempting to load does not
      contain any C functions.
       From entry point main at compile unit offset +08EAC488
      at address 08EAC488.
      

    Has anyone run into this before? I went and wrote a test C main and a test DLL to see if that would work and of course it did. So I am suspecting that the CBC warnings have something to do with my troubles.

    Answer

    After looking at the code, as the message indicates, "THERE are NO C FUNCTIONS in THE LOAD MODULE". The C signature is missing. Look at your link-edit map for the DLL module and verify if CEESG003 CSECT is resolved.

    Check your concatenations of datasets to your steplib on GO step. If you have an old load module with the same name as the DLL that you are attempting to load and that load module does not contain any C code you would receive this message.

    Question - C++/c89 Options

    I am trying to compile source contained in an MVS partitioned data set from the OpenEdition shell using the c++ shell command. However, I would like to place the object deck from the compile in the HFS, and in order to do that I am trying to use the following option:

    c++ -Wc,obj(/u/tonyn/webvis/visitor.o),notempinc ....(etc)
    

    However, I get the following message when I try to run this:

    FSUM7332 syntax error: got (, expecting Newline
    

    Am I doing something wrong or is this a possible bug?

    Answer

    Try escaping the parenthesis on the command line, e.g.,

    c++ -Wc,obj\(/u/tonyn/webvis/visitor.o\),notempinc ....\(etc\)
    

    Question - C/C++ Compiler and Library Products

    Does anybody know of a document that sets out in a clear, easy to understand way, all of the mainframe C/C++ library and/or compiler products and details of which ones supersede which?

    Answer

    You might want to check out the IBM C/C++ for MVS/ESA(*) Compiler and Run-Time Migration Guide (SC09-2002-1). I can try to explain the MVS C/C++ story.

        Compilers                 Run-Time Library
        ------------              ----------------
          V1R1 C             ----    V1R1
            |                          |
          V1R2 C             ----    V1R2
            |                          |
          V2R1 C             ----    V2R1
            |                          |
          ADV1R1 C           ----    LEV1R1
            |                 \--    LEV1R2
            |                          |
          ADV1R2 C           ----    LEV1R3
            |                 \--    V2R2
            |                          |
          V3R1 C/C++/MVS     ----    LE V1R4
            |                          |
          V3R1 C/VM          ----    LE V1R5
          V3R2 C/C++/MVS     ----    LE V1R5(latest and greatest)
            |                          |
          OS/390 R1          ----    OS/390 R1
          (reship of V3R2)           (reship of LE V1R5)
            |                          |
          <watch this space> ----    <watch this space>
    
    Each compiler level is shown beside the library it runs on.
    
    V1R1      5688-040  c.1988  C/370 V1R1 Compiler
              5688-039  c.1988  C/370 V1R1 Library
    V1R2      5688-040  c.1989  C/370 V1R2 Compiler
              5688-039  c.1989  C/370 V1R2 Library
    V2R1      5688-087  c.1991  C/370 V2R1 Compiler
              5688-088  c.1991  C/370 V2R1 Library
    ADV1R1    5688-216  c.1991  AD/Cycle C/370 V1R1 Compiler
                                Follow-on to C/370 V2R1 Compiler
    LEV1R1    5688-198  c.1991  LE/370 V1R1 Libraries
                                First release of Language Env/370;
                                "Follow-on" to C/370 V2R1 Library
    LEV1R2    5688-198  c.1992  LE/370 V1R2 Library
    ADV1R2    5688-216  c.1994  AD/Cycle C/370 V1R2 Compiler
                                the "switchable" compiler:
                                 - runs on either LEV1R3 or V2R2;
                                 - generates code for either
                                   LEV1R3 or V2R2;
    LEV1R3    5688-198  c.1994  LE/370 V1R3 Library
                                also shipped as part of MVS/ESA
                                SP5.1 OpenEdition AD/Cycle C/370
                                Language Support Feature
    V2R2      5688-088  c.1994  C/370 V2R2 Library
                                Follow-on to the C/370 V2R1
                                Library, intended to help
                                customers migrate to LE/370;
    V3R1      5655-121    1995  C/C++ for MVS V3R1 Compilers
                                Follow on to ADV1R2 Compiler
    LEV1R4    5688-198  c.1995  LE V1R4 Library for MVS & VM
                                nee LE/370, also shipped as the
                                C/C++ Language Support Feature of
                                MVS/ESA SP5.2.0
                                C/C++ Language Support Feature
    V3R2      5655-121    1995  C/C++ for MVS V3R2 Compilers
    V3R1      5654-033    1995  C for VM V3R1 Compiler
                                (This C compiler is roughly
                                equivalent to the
                                C compiler in V3R2 C/C++ for MVS)
    LEV1R5    5688-198    1995  LE V1R5 Library for MVS & VM
                                also shipped as part of MVS/ESA
                                SP5.2.2 C/C++ Language Support
                                Feature
    OS/390 R1 5645-001    1996  OS/390 R1 includes the C/C++ for
                                MVS V3R2 Compilers as an
                                optional feature and the LE V1R5
                                Libraries as a standard feature
    

    Question - FSEEK Problem

    I have an application that randomly reads a large binary file. I'm encountering problems with the 3rd fseek in a series of fseeks and freads. The file offset is identical for the 2nd & 3rd fseek, yet the 3rd fseek fails with the perror "invalid fseek offset". I have a stub program that recreates the error. If I remove the freads, all 3 fseeks work. None of the freads generate errors or read past the end of file. The file is opened with the "rb" attribute and the DCB parms are RECFM=F, LRECL=4096, BLKSIZE=4096.

    Any suggestions would be appreciated.

    Answer

    Could it be that the fread before the 3rd fseek positioned the file such that the offset from the 3rd fseek would make it goes past the end-of-file mark? You can tell this if you know the size of the file. First you could insert a ftell() before the 3rd fseek (i.e. the one that got problem); the result from this ftell() would tell you how far you are from the beginning of the file; then you know how far you are from the end of the file. Compare this with the offset of the 3rd fseek. It should be larger than the offset otherwise you would get the error as described. To find out how large the file is you first fopen() it; position to the end (fseek(.., 0L, SEEK_END); do ftell(..) which returns the offset at the end of file hence file size.

    Question - IEF642I EXCESSIVE PARAMETER LENGTH IN THE PARM FIELD

    I'm trying to use the 3.1 compiler, and having some problems passing parameters to it. My current JCL looks like:

    //CMPPS00 EXEC YEDCC,INFILE='ACP.SOM.FIX.SOMK.C(SOMID)',
    //  OUTFILE='SOM0000.DEVP.TEST.OB(SOMIDRQ),DISP=SHR',
    //  CPARM='LO OPT SO LIS RENT EXP SHOW DLL EXPO XRE AGG',
    //  CPARM2='DEF(_MVSDLL,_MVS,_RETAIL,MISOM,_NODBCS,_SOM_ALL) TEST'
    

    I need to add one more parameter, but when I do I get the IEF642I excessive parameter length error.

    I've tried adding it with CPARM3, or to one of these lines, but I still get the error. I think none of these options are default, otherwise I'd remove them to make more space. I also think I've got the shortest abbreviations allowed. And any clues how I can add one more option to the DEF as I want _PERF added to the DEF field?

    Answer

    Our V3R2 C and C++ compilers provide a solution for this problem - you can specify the OPTFILE compile-time option which lets you specify an options file to read. For example:

      //COMP     EXEC  EDCCL,CPARM='OPTFILE(DD:OPTS)'
      //COMPILE.OPTS DD *
          OPTIMIZE(2),NOTEST(ALL),MARGIN(1,72),
          SEQUENCE(   73,80),CHECKOUT(NOACC,NOIN,PORT),SOURCE)
      /*
    

    For V3R1, OPTFILE is available for C++ only. For earlier releases, it is not available.

    Question - COMPARE AND SWAP

    How do you do a "COMPARE AND SWAP" using C/370?

    Answer

    The built-in function cs() is compare and swap and the built-in function cds() is compare double and swap.

    For more information see the Library Reference manual.

    Question - deleting member of a PDS

    Can anyone tell me how to delete a member of a PDS from within a C/370 program.

    Answer

    remove("my.pds(member)");

    It's declared in stdio.h.

    Question - types.h

    I have a program that compiles with no errors with C/370-compiler (5688-187) but get Syntax errors when compiled with AD/Cycle C/370 (5688-216). I have to put in some new statements to be able to compile with no errors. The question is why there is a difference between the two C-compilers? The program follows:

      #include <stdio.h>
      #include <manifest.h>
      #include <rpc.h>
      #include <rpc/types.h>
      #include <xdr.h>
      #include <bsdtocms.h>
      /* fr}n a004uvs.test.h */
      #include <ibme.h>
      #include <ibmes.h>
      #include <ibmex.h>
      rReoR *test_1(void)
      {
      rReoR r;
      long from_to;
      static char roll[10000];
      for (from_to=0;from_to<9999;from_to++)
        roll[from_to] = 'F';
      roll[9999] = ' 0';
      r.s = roll;
      r.rStatus = 1;
      return(&r);
      }
    

    The same program with added statements

      #include <stdio.h>
      #include <manifest.h>
      typedef  char *    caddr_t;            ADDED
      typedef unsigned short  u_short;       ADDED
      typedef unsigned short  ushort;        ADDED
      typedef unsigned int    u_int;         ADDED
      typedef unsigned int    uint;          ADDED
      typedef unsigned long   u_long;        ADDED
      typedef unsigned long   ulong;         ADDED
      #define FALSE 0                        ADDED
      #define TRUE  1                        ADDED
      #define bool_t  int                    ADDED
      #include <rpc.h>
      #include <rpc/types.h>
      #include <xdr.h>
      #include <bsdtocms.h>
      /* fr}n a004uvs.test.h */
      #include <ibme.h>
      #include <ibmes.h>
      #include <ibmex.h>
      rReoR *test_1(void)
      {
      rReoR r;
      long from_to;
      static char roll[10000];
      for (from_to=0;from_to<9999;from_to++)
        roll[from_to]  = 'F';
      roll[9999]  = ' 0';
      r.s = roll;
      r.rStatus = 1;
      return(&r);
      }
    

    Answer

    Problem is not in the compiler. The behaviour is unchanged.

    The define's that you are inserting are provided in the "types" header file provided with TCP, etc. The real name for this header is "rpc/types.h", but on MVS and VM, it is called "types.h" due to the 8-character name limitation.

    The problem surfaced because in AD/Cycle C 1.2, we introduced a header file called "types.h". This header file contains definitions for POSIX(**) compliance on MVS under OE. The header is found ahead of the RPC version of "types.h" in the search order of syslib, so is included. If you were to change the dataset order in syslib, all would be well again (unless you wanted anything out of our "types.h". In C++ V3, we introduced a "sys/types.h" file, and a mechanism (SYSPATH/USERPATH) to allow the precise selection of which instance of "types.h" is desired. There is no such feature in AD/C.

    You can either:

    Question - Getting milliseconds from system clock

    I'm a new user of C/370 and I need to get the milliseconds from the system clock to create a timestamp as part of a qualifier of dataset name. I've looked through the available examples and fail to see where I can directly issue a get_time command to load a "time-tm" struct with hours, minutes, seconds, and milliseconds.

    Do you have an example of C/370 sample coding which would allow me to achieve the above?

    Answer

    Try the code below. The first printf is in seconds only, the second is seconds (+ milliseconds) since 00:00:00 on Oct 14, 1582 and the third is the local YYYYMMDDHHMMSSTTT (TTT is thousandths). Thousandths of a second is not available directly from C library - LE/370 service must be used. (TTT is not defined as part of ANSI - the language only goes to seconds).

     #include <leawi.h>
     main()
     {
     _FEEDBACK fc;
     _INT4     lilian_date;
     _FLOAT8   local_date;
     _CHAR17   char_date;
     CEELOCT(&lilian_date,&local_date,char_date,&fc);
     printf("currently: %d\n",lilian_date);
     printf(" or        %f\n",local_date);
     printf(" or        %s\n",char_date);
     }
    

    Question - Passing Parameters

    I was attempting to pass values into a C program with PARM="p1,p2" option like you can do in Assembler or Cobol. Is that possible in C/370?

    Answer

    Under LE/370, parms are passed to the program much like they are elsewhere, except that the "user parm" list must be preceded by a slash (/). LE/370 is parm driven as well, so in order for LE to figure whose parm is whose, any LE parms go ahead of the slash. eg. To pass "RPTOPTS(ON)" and "RPTSTG(OFF)" to LE/370 and pass "p1,p2" to your C/370 (or COBOL/370 or PL/I /370 ...) application, you would use

     PARM='RPTOPTS(ON),RPTSTG(OFF)/p1,p2'
                                  |
             this side goes to LE | this side goes to application
    

    If you specify "#pragma runopts(EXECOPS)" in your source code, you remove the ability to specify the LE options, and cause the entire parm (RPT.../p1,p2) to be passed to C/370 (including the slash). If you use this feature, you are responsible for finding the slash, and hence, the start of the user parm.

    Question - Rand function in C/370

    I've attempted to decrease the RAND_MAX macro variable value from 32767 to another number by undefining the variable (#undef) and redefining it (#define) with a new value. When I call the Rand function using the default seed, the value still returns values greater than the new value I've set which is less than 32767.

    I've discovered that the rand function is compiled with the RAND_MAX 32767, hence it is unchangeable. Am I attempting to alter the RAND_MAX value in an incorrect manner?

    Answer

    RAND_MAX is an informational value that tells you what the upper limit is. If you want a lower limit, or a different range, you will need to re-map it. To re-map the value from rand() to be in the range 0 to 1234, you would code something like:

          value = ((float)rand()/RAND_MAX) * 1234;
    

    Since rand() will return a value in the range 0 to RAND_MAX, this will generate values 0 to 1234. This is somewhat consistent with what is done in other models where the value is in the range 0 to 1 (ie. a decimal value to be applied to the range to come up with the real value).

    Question - localtime() function

    I have a problem with the localtime() function in C/C++ it is returning GMT instead of CST when called. I understand I can customize the offset by running EDCLLOCL proc in the sample library delivered. The method for making this modification then using it are doing this is confusing. It is referenced and explained in several manuals but I am still unclear on how to proceed.

    First the customization of C/370 support for internationalization for LE 1.5.0 to support CENTRAL STANDARD TIME. The pds member in SCEESAMP(EDCLLOCL) should be modified and run

    
      Original Text:
    EDCLOCI  EDCLOCTZ TZDIFF=1500,TNAME=,                        *
             DSTSTM=0,DSTSTW=0,DSTSTD=0,STARTTM=0,SHIFT=0,       *
             DSTENM=0,DSTENW=0,DSTEND=0,ENDTM=0,DSTNAME=,        *
             UCTNAME='UTC'
             END
    

    1. What should the above Text look like to return by default Central Standard time that adjusts for Daylight savings time on the Second Sunday in April at 2:00AM and the Second Sunday in October at 2:00AM automatically?

    2. Could you give me a program example that returns the correct time using the localtime() function?

    Answer

    1. Assuming the short names for the standard and daylight saving times are 'CST' and 'CDT' respectively, and that the daylight saving time shift is 1 hour, and CST is a six-hour offset from GMT, the text should look as follows:
      EDCLOCI  EDCLOCTZ TZDIFF=360,TNAME='CST',                     *
               DSTSTM=4,DSTSTW=2,DSTSTD=0,STARTTM=7200,SHIFT=3600,  *
               DSTENM=10,DSTENW=2,DSTEND=0,ENDTM=7200,DSTNAME='CDT',*
               UCTNAME='UTC'
               END
      

      TZDIFF is calculated as number of minutes of GMT (6*60).

    2. The following program prints the locale name of the current locale, and three different times:

      1. Current calendar time

      2. A calendar time in the past (January 15, 1996)

      3. A UTC (aka GMT) equivalent of 2.

      If the customization was done correctly, the current time should correctly reflect the local time at execution, and the times under 2. and 3. should differ by the time zone difference.

        #include <time.h>
        #include <locale.h>
        #include <stdio.h>
      
        void main()
        {
         struct tm lcl;
         time_t    lcltime;
         time_t    curtime;
      
         lcl.tm_year  =  1996 - 1900;
         lcl.tm_mon   =  0;
         lcl.tm_mday  =  15;
         lcl.tm_hour  =  19;
         lcl.tm_min   =  25;
         lcl.tm_sec   =  30;
         lcl.tm_isdst = -1;
      
         lcltime = mktime(&lcl);
         curtime = time(NULL);
      
         printf("locle   =%s\n",setlocale(LC_TOD, NULL));
         printf("cur time=%s\n",asctime(localtime(&curtime)));
         printf("old time=%s\n",asctime(localtime(&lcltime)));
         printf("gmt time=%s\n",asctime(gmtime(&lcltime)));
      
         return;
        }
      

    Question - Dynamic loading of asm modules

    I'm using c/c++ v3r2 on MVS 5.2.2. I need to dynamically load some assembly language modules to be called from my C (not C++) program. The program runs under OpenEdition, but the routines are in a PDS (//'sys1.csslib'), not in the HFS.

    Can I do this with the C DLL functions? If so, how? All documentation references to DLLs are in the context of C/C++, not assembly. Or do I have to write assembly routines to LOAD and DELETE the library modules?

    Answer

    For DLL support, you need to compile the DLL with the DLL option, then prelink it. This will create a side-deck to be included with the calling code. Unfortunately, you can't really use assembler this way since the DLL-building portion is part of the C support, not at the system level.

    "fetch" is your best bet for non-C++.

    Question - Writing floating point data to a file

    I have a C variable defined as "float". I need to write the value of that variable to a file in its native 370 floating point representation. In other words, if the value of the variable is 0.04, I would like to write four bytes to the file with the value '3FA3D70A'x (which is the 370 floating point value for 0.04, or as close as 4 bytes can get). There doesn't seem to be any printf format that will let me do this. Also I need to mix text fields and binary fields in the same record. Your suggestion requires opening the file "wb". Doesn't that mean that printf would not work?

    Answer

    printf works ok to a wb file. However, control characters such as '\n' will just go into the file as their hex equivalents.

    You could open the file text but if the hex value of your float number contained any control values (line x15 which I believe is newline) they would be parsed as their control value NOT the hex digits (and you would get a new line in the middle of your number). For example the following code:

    #include <stdio.h>
    float x=0.04;
    
    main() {
     FILE *fp;
     fp=fopen("test.file","wb");
     fprintf(fp,"this is a string ending in a newline\n");
     fprintf(fp,"this is an integer %d\n",10);
     fprintf(fp,"this <%s> is nested string %d\n","string string");
     fwrite(&x,sizeof(float),1,fp);
     fclose(fp);
    }
    
    (on VM so VM default wb fopen values) generates a FB 80 file with two records as follows:
    this is a string ending in a newline this is an integer 10 this <string string>
    A88A48A484AA9898489889848948498A98981A88A48A489489A88894FF1A88A44AA98984AA989864
    3892092010239957055495709501055639555389209201509535759010538920C2399570239957E0
    -------------------------------------------------------------------------------
    is nested string 0  tP
    8A498AA884AA98984F13AD0000000000000000000000000000000000000000000000000000000000
    9205523540239957005F37A000000000000000000000000000000000000000000000000000000000
    

    If this was a text file and I used fwrite to write the integer 8981 (x'2315') to the file I would get a file with x'23' and then a newline. Both methods have their drawbacks. There are definitely some other methods to do what you want. If we knew more about the format of your data (i.e. are all records in the file of a fixed format, or a limited number of formats?) there may be other suggestions.

    Question - Porting from OS/2

    We are porting applications from OS/2 and we need some macro symbols to identify the MVS C++ sections in the code . Is there a way to undefine the __IBMCPP__ macro symbol ? Is there a system defined macro symbol which is defined under MVS but not under OS/2 ?

    Answer

    The MVS macro names are defined on page 214/216 in the v3r2 language reference. They were not in the previous release. You are probably looking for __MVS__, __HOS_MVS__, __TOS_MVS__, __370__.

    Question - forCurson

    Does C++MVS have a collection class macro forCursor? I see forICursor that requires a #define, but C++ for AIX has a forCursor that doesn't require the #define. If there is forCursor, where is it documented?

    Answer

    The macro definitions forCursor and forICursor are included in ibcllct.h. The macro forICursor is the new version and forCursor is kept for backward compatibility. In the AIX version the macro definition is included in icursor.h.

    The macros are mentioned in the Open Class Library User's Guide chapter 8.5.1 (Iteration using Cursors) and chapter 15.1 (Compatible Items).

    Question- DLLs with cross-references

    I have two DLLs which have cross-references. That is a function in DLL1 calls some function in DLL2 and vice versa. Now, I want to do explicit loading of these DLLs using "dllload()". Once I load one DLL, the dllload() fails for the next one. The error message interpreted from the errno is:

       EDC5207S Load request for DLL load module unsuccessful.
    
    In the documentation that I have I couldn't locate the EDC5207S message.

    So the question is, Is it possible to explicitly load two DLLs which have cross calls.

    Answer

    EDC5207 error message indicates that it could not the DLL load module into storage. Check that your steplib datasets include the two DLL load modules.

    As far as cross-reference calls are concerned, if your DLL application looks similar to this:

     DLL application               DLL 1                 DLL 2
    +-----------------+      +-------------+      +-------------+
    |- load DLL1      |      | f1(...) {   |      | f2(...) {   |
    |  get f1 pointer |      |             |      |             |
    |- load DLL2      |      |   f2(...);  |      |  f1(...);   |
    |  get f2 ptr     |      |             |      |             |
    |                 |      | }           |      | }           |
    |  invoke f1()    |      | ...         |      |             |
    |  invoke f2()    |      +-------------+      +-------------+
    |- dllfree DLL1   |
    |- dllfree DLL2   |
    +-----------------+
    
    then the only thing to consider is that once a cross reference call is made from DLL1 to DLL2 (f1 will load DLL2 implicitly) or from DLL2 to DLL1 (f2() will load DLL1 implicitly), then dllfree() will not free the DLL because it is loaded both implicitly and explicitly. dllfree() will free a DLL load module if and only if it is only loaded explicitly.


    A word from your editor

    If you did not get a copy of our previous editions, just let us know and we will send them to you.

    You can download previous editions for online viewing from our anonymous ftp server (ftp.software.ibm.com). Directory /s390/c370 contains directories /news, /oldnews and /samples. /oldnews is broken down by year and /samples is broken into individual samples (eg. /codepage, /debuggable_malloc).

    If you haven't already sent for your free subscription to this newsletter, now is the time to mail it in. If you prefer, mail or fax your business card to the address/phone number on the Reader's Comment Form. You can also send a message containing your name, full mailing address and phone number, in case we have to talk to you to inetc370@vnet.ibm.com or IBMMAIL(CAIBMRXZ).

    Please keep those cards, letters, faxes and messages coming in to us so that we can continue to provide this service. We really thank the many of you who have already sent your comments and subscriptions in. It's a great help if you include your phone number with any correspondence. Thanks!!


    Coming Soon

    In future issues, we'll have some performance tips and answer some more of your questions. Thanks for reading; please let us know what you think of this newsletter.

    This newsletter was produced by the IBM Software Solutions Toronto Laboratory. For further information on any of the products mentioned, please contact your local IBM office, or an authorized IBM Business Partner.

    Numerous product references in this publication are registered trademarks or trademarks of International Business Machines Corporation, unless otherwise indicated. IBM Canada Ltd., a related company is a licensee.

    This newsletter was created and marked for processing using IBM BookMaster (*) (Program Number 5688-015) and IBM Document Composition Facility (DCF)(Program Number 5748-XX9). The final copy was printed on an IBM 3825 Page Printer, an Advanced Function Printer.

    This newsletter is © Copyright IBM Corporation 1996. In Canada - © Copyright IBM Canada Ltd. 1996.


    C/370 Compiler News Volume 4 Number 3 July/96 Issue

    Reader's Comment Form

    1. Did you find this newsletter useful?

    2. Is there any way you think we could improve this newsletter?

    3. Is there any C/370 compiler-related subject you would like to see addressed in this newsletter?

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    ____________________________________________________________________

    Please note:

    Thank you for your cooperation and help. You can either mail this form to us, hand it into an IBM office for forwarding or send a message containing your full mailing address and phone number to IBMMAIL(CAIBMRXZ) or inetc370 @ vnet.ibm.com.

    You can also fax the form to us. Our fax number is 416-448-2893. Please mark your fax for the attention of Gord Sinclair. Thanks.

    C/370 Compiler News Volume 4 Number 3 July/96 Issue

    Reader's Comment Form

    Fold here and tape.........fold here and tape.........fold here


        Gordon Sinclair
        Software Solutions Toronto Laboratory
        IBM Canada Ltd
        91/604/895/TOR
        895 Don Mills Road
        North York
        Ontario, Canada
        M3C 1W3
    


    Fold here and tape.........fold here and tape.........fold here
    Footnotes:

    ( ) Products marked (*) are trademarks or registered trademarks of International Business Machines Corporation, unless otherwise indicated. Company, product or service names marked (**) may be a trademark or service mark of others.