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
Welcome to the July, 1996 Issue of the C/370 Newsletter
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.
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.
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 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.
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.
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.
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.
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.
Tells you how often a line of code is executed. You can quickly identify untested areas in your program or potential bottlenecks.
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.
C Set++ for the Solaris Operating System supports:
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
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:
//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) />
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++:
//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) />
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 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.htmland surf from there or you can go directly to the URLs below.
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
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
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.
subscribe C370-l your_full_name
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.
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.
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:
#include <types.h> to #include "types.h"and put that one in the USERLIB instead of SYSLIB
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
Answer
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).
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.
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!!
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.
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
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.
Gordon Sinclair Software Solutions Toronto Laboratory IBM Canada Ltd 91/604/895/TOR 895 Don Mills Road North York Ontario, Canada M3C 1W3
( ) 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.