Welcome to the Second Issue of the C/370 Newsletter

IBM Corp 1992

                  370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370
              370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
         370 370 370 370 370 370 370 370 370 370 370 370 370 370
             370 370 370 370 370 370 370 370 370 370 370 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

June 1993 Volume 1 Number 2


Table of Contents

Welcome to the Second Issue of the C/370 Newsletter

  • In This Issue
  • System Programming Facilities
  • Functions available in the System Programming Environment
  • Considerations for Using the System Programming Facilities.
  • Types of Applications
  • C/370 V2.1 to LE/370 V1.2 Migration Hints and Tips
    Another IBM "C" Family Newsletter
    C/370 Performance Hints & Tips
  • Inlining Functions
  • C/370 Portability Hints & Tips
    SAA AD/CYCLE CODE/370
  • CODE/370 Productivity Features
  • You ask, we answer
    Missed our Premiere Edition
    A word from your editor
    Coming Soon
  • Reader's Comment Form

  • Welcome to the Second Issue of the C/370 Newsletter

    Well, the first issue of the newsletter is under our belt and now we have subscribers waiting for this issue. Thanks for subscribing and for your questions. We have passed your comments/questions over to our experts here. We have been able to answer some of your comments and questions quickly in this newsletter and will have more in the future.

    In This Issue


    System Programming Facilities

    When C/370 applications are constructed there are many routines needed to support the C/370 environment that are not included in your load module. Instead, these routines, contained in either Language Environment/370(TM) (LE/370) or the C-PL/1 Common Library and the C/370 Specific Library, are dynamically bound at run-time. This reduces the size of the load module to its practical minimum and provides for the sharing of C/370 library code by allowing its placement in Extended Link Pack Areas in MVS or Saved Segments in VM/CMS.

    The Run-Time Library provides facilities to set up the environment, handle termination, and provide storage management, error handling, interlanguage calls and debugging support. In situations where not all of these services are needed or available, the system programming C facilities can provide a reduced environment for your application.

    You can write applications that either do not use any of the run-time libraries or just parts of them. For example, a system programming application could use the C library function printf but not use the library initialization routines; the system programming facilities would handle initialization. ( )

    Functions available in the System Programming Environment

    Many functions normally provided by the Run-Time Library can be made available in this environment. This includes:

    As well, new memory management functions are available only in the system programming environment. These are:

    Storage allocated by these functions is not part of the heap, so freeing it is your responsibility (using free()); it is not automatically freed when the environment is terminated.

    In this environment, low level memory management functions and supervision (loading and deleting executable code) are supported by low level routines that you can replace to support non-standard environments.

    Considerations for Using the System Programming Facilities.

    The following items should be considered when using any system programming environment:

    Types of Applications

    System programming capabilities allow you to run routines without a Run-Time Library or with just the C/370 library functions available and to:

    For more information on the System Programming Facilities of C, please refer to the chapter entitled System Programming Facilities in your Programming Guide (SC09-1384 for C/370 2.1 or SC09-1356 for AD/Cycle C/370).


    C/370 V2.1 to LE/370 V1.2 Migration Hints and Tips

    IBM(TM) SAA(TM) AD/Cycle(TM) Language Environment/370 is a common run-time library that provides a predictable, consistent run-time environment for languages. This common library, with its consistent calling method, provides enhanced capabilities for you to:

    If you have decided to use LE/370 or are considering using LE/370 here are some things to consider when migrating from C/370 V2.1 to LE/370 1.2.

    1. FORTRAN InterLanguage Communication(ILC) is not yet supported by LE/370 and LE/370 requires ESA. COBOL, C/370 and PL/1 ILC is fully supported in LE/370 Release 2.

    2. Old load modules compiled and linked with C/370 will run on LE/370. However, modules making COBOL ILC calls and modules calling "debugging" services (cdump, csnap, ctrace, ctest) will have to be relinked from original objects or relinked from load modules using csect replacement. LE/370 provides the necessary csects. You should also be aware of these changes.

      Some incompatible old C modules need the old C/PLI environment. The only way to control which environment is initialized is to arrange the concatenation of libraries correctly. You can do this selectively for every module invocation by placing SCEERUN after SIBMLINK/IBMLIB in the concatenation order of libraries or universally removing the IBMBLIIA alias from EDCLIIA in SCEERUN.

    3. Message destination (STDERR) has been changed. It no longer shares the same filename with STDOUT by default. It is now controlled by MSGFILE run option and MSGFILE defaults to SYSOUT.

      The text and message numbers of C strerror/perror messages (prefixed EDCxxxxa) have been changed to fit LE/370 model. perror() messages will change dynamically with the LANGUAGE run-time option.

    4. Some return codes have been changed.

    5. EXECOPS default is now controlled by compiler and can change interpretation of user parameters. CMS tokenized parameter list unsupported. That is, if a user invokes a C main program from an assembler driver that built a tokenized parameter list, it will now fail.

    6. Some considerations if you are using CICS.

    7. Cobol conditions can drive C signal handlers with Exceptions limited by "errcount". The default is set at install. We recommend "0" for C.

    8. Be aware that stack increment defaults to 512K (was 4k). If you need 4K increments use STACK(4K,4K,ANYWHERE,KEEP).

    For more information, please refer to the IBM SAA AD/Cycle C/370 Migration Guide(SC09-1359).


    Another IBM "C" Family Newsletter

    C Set ++(TM) News(formerly OS/2(TM) Compiler News) is an informal developer to developer newsletter published by the OS/2 C/C++ group in IBM's PRGS Lab in Toronto. Targeted directly at people who use WorkSet/2 (C Set/2(TM) , WorkFrame/2(TM) and the Programmer's ToolKit) and the newly available C Set ++ (compiler, debugger, TK, class libraries, trace analyzer, browser, WorkFrame/2), the Newsletter aims to provide both general and technical information about these products. This ranges from overviews through technical articles to a detailed Q&A section. A Reader's Reply Form is also included for feedback.

    The May 93 edition is available and has:

    1. the announcement of C Set ++ with order numbers and prices

    2. a peek at the upcoming WorkFrame/2 V2

    3. first details of another ColoradOS/2 conference

    4. notes on upcoming C++ education

    5. a story on IBMLink

    6. an article on usability

    The newsletter is softcopy on CompuServe and OS2BBS and several other nets. Hardcopy is available directly from IBM. To be on the mailing list anywhere in the world, send (or fax to 416-448-6057 attn MJ Houghton) your name and address (phone number is useful too) to:


    C/370 Performance Hints & Tips

    Inlining Functions

    C/370 V2 and AD/C C/370 V1 have a compile time option called Inline. The Inline This eliminates the linkage overhead and exposes the entire inlined function to be optimized by the global optimizer. You should only use the Inline

    In order to get maximum performance improvements , the Inline The REPORT suboption should be used when tuning your code.

    In either mode, there are two types of calls which are NOT

    Automatic Mode

    To provide assistance in choosing which routines to inline, you can compile with the INLINE(AUTO,REPORT,,). Specifying larger values of threshold and limit will inline more functions. Beware that, when functions become too large, run-time performance can degrade.

    You should be aware that inlining a function which is rarely invoked can degrade performance. The #pragma noinline

    Once you are satisfied with the selection of inlined routines, you should add the appropriate #pragma inline directives to the source. That is, once the selected routines are forced with these directives, you can then compile the program in selective mode. This way, you do not need to be affected by changes made to the heuristics used in the auto inliner.

    Automatic mode is provided to assist you in starting to optimize your code. It is not recommended for final compilation of production level code.

    Selective Mode

    If you know exactly which functions are frequently invoked from within a compile unit (You can use the automatic mode, debug tools or execution time analyzers to get this data), you can simply add the appropriate #pragma inline directives in your source and compile with INLINE (NOAUTO,REPORT,,).

    If your code contains complex macros, the macros can now be made into static routines at no execution time cost. All static routines which interface to a data object can be placed into a header file.

    For best run-time performance, the inliner should be used in selective mode (INLINE(NOAUTO)) to fine-tune your final application rather than rely on the inliner in automatic mode (INLINE(AUTO)).


    C/370 Portability Hints & Tips

    Sometimes it is impossible to avoid using nonportable constructs and there may be situations where you may want to use nonportable constructs. For example,

    Here are some of the methods that you can use to make it easier to move nonportable code from one platform to another.

    For more information, please refer to the Portability Guide for IBM C (SC09-1405).* ----------------------------------------------------------------------


    SAA AD/CYCLE CODE/370

    AD/Cycle CoOperative Development Environment/370 (CODE/370) is an integrated Edit / Compile / Debug Environment for application developers. The COBOL and C programmers in your shop can use the CODE/370 tool to develop and maintain existing and new applications in the AD/CYCLE framework.

    CODE/370 is integrated with the following products to form the AD/CYCLE 3GL framework of application development, build, test and maintenance:

      AD/CYCLE Language Environment*/370, a common runtime Environment
      AD/CYCLE COBOL/370 and AD/CYCLE C/370 compilers
    

    Combined, these products allow existing applications to be migrated to the AD/CYCLE framework.

    CODE/370 Productivity Features


    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 like to ask us, have a comment about C/370, or just want to subscribe to this newsletter, please use the Reader's Comment Form at the back of this newsletter.

    Question-MVS Record Problem

    I've taken a program written on a PC and "PORTED" it to our MVS system. I've made the input dataset RECFM=FB LRECL=80 and BLKSIZE=1600. I've placed these keywords in the fopen statement also.

    When reading in data, however, it seems to be streamed together. IE blanks at the end of a line are ignored and then the characters in the next line are run on together until 80 characters fill a record.

    I've found that if I put non-blanks at the end of a line I can make it work OK, but of course that's not what I want either. I tried changing the EBCDIC blanks '40'x to '60' and examined the characters as they come-in. Interesting enough it seems that when the last character in a record is encountered I get a EBCDIC '40'x blank.

    Answer

    On page 207 of the V2R1 Programming Guide under "Stream I/O - Text Streams" you will find

    "For fixed-length records....On input, trailing blanks are stripped and the new-line character is inserted at the end of each record".

    Since you opened "r", you have opened the stream as a Text stream. The blank you see after each record is a new line character. You can't see it because it isn't a visible character.

    If you want all of the blanks then either open the file as Binary for Record I/O, or else copy the fixed file to a Variable file. For variable files, although trailing blanks are not stripped, you should be aware that a single blank record represents an empty C record(ie. just a newline character).

    Question-Abend doing shift left with OPT(2)

    We have encountered an OC8 (overflow abend) in our application that is compiled using C/370 V2R1 on VM. The following program isolates the case where the problem occurs.

     main()
     {
     unsigned short usCount;
     unsigned long ulMask;
     ulMask = 0x00000001;
     for (usCount =0; usCount,8*sizeof(unsigned long); usCount++)
        {
        ulMask = ulMask << 1;
        }
      }
    

    The assembler generated for the shift left in OPT(0) and OPT(1) is SLL. This works fine. When using OPT(2), the optimizer decided to use AR. AR operates on 32 bit signed value and hence overflows when the 1 shifts to the high order bit when the fixed point overflow mask is set to 1. I realize that the default for the fixed point overflow mask is 0.It was a call to another product that turned the mask on. However, I cannot accept the fact that the optimizer uses an instruction that could cause an overflow - especially when I specifically coded the value as UNSIGNED LONG.

    Answer

    Oops, this will be fixed in the next release.

    Question-Size of an enumeration type

    Shouldn't sizeof(ETYPE)==4, where ETYPE is an enumerated type, regardless of the number of elements in the enumeration? The various C books say that enumeration constants are ints. To me this implies that sizeof(int)==sizeof(ETYPE); and this is what I've found in various implementations. But not under C/370:

       typedef enum {
         MOO,
         COW,
       } myenum;
       main();
       {
        printf("%d\n", sizeof(myenum)); /* prints 1 */
        printf("%d\n", sizeof(MOO));    /* prints 4 */
       }
    

    In fact this is not even self-consistent. The C reference manual in the back of K&R (ANSI version) at A.7.4.8 says that sizeof() "yields the number of bytes required to store an object of the type of its operand". If it requires 4 bytes to store MOO, then it requires at least 4 bytes to store a "myenum" which contains MOO.

    Answer

    For better or for worse, C/370 figures out how much space you need to store the values of an enum. If it only needs a char, it only uses a char. If it only needs a short, it only uses a short.

    What I do if I want something to be 4 bytes in size is to add a dummy member as follows:

       enum Colour {
         R=1,G=2,B=3,DummyColour=65536
       };
    

    Since 65536 doesn't fit in a short, the sizeof(enum Colour) will be 4.

    The behavior of C/370 is consistent with ANSI. It is important to distinguish between an enum constant and an enum variable. ANSI specifies that an enum constant must have type int. While an enumerated variable shall be compatible with an integer type; the choice of type is implementation defined. Thus, C/370 tries to conserve storage by figuring out the smallest space that will fit.

    Question-Virtual Storage Problems

    We are using C/370 (V2R1M0) to compile some very large programs, and we expected to (eventually) have virtual storage problems with some of them. The current problem is that we are having virtual storage problems with programs that are much smaller (in terms of LOC) than those with which we expected to have problems originally. The program currently having problems does include a lot of headers, 267 to be exact, which primarily contain type definitions and macros; but even the resulting expanded source from the preprocessor is smaller than the original programs that we thought would have problems.

    Can anyone offer suggestions or comments concerning the behavior of the preprocessor or the compiler, which might point towards specific types of constructs or coding practices that have a stronger potential for causing high virtual storage usage.

    Answer

    Here are some things which would consume memory in a direct compile but not when compiling the preprocessor (expanded) output:

    Question- How does 'fetch' work?

    What happens when I use the C/370 'fetch' function to dynamically load a module, and then call it? Does it just branch to it so I run under the same PRB, do I get a new PRB, or do I get a new task?

    The reason I ask is that I am doing some TCP/IP socket programming and seem to lose access the the socket when running in the 'fetched' code.

    Answer

    On MVS, fetch() performs an OS LOAD to load the module. It then creates a stub that performs writable static switching and calls the entry point using a BASSM instruction (will switch AMODE if necessary). You cannot have values in global static areas and expect them to be present on the other side of the fetch. This won't work since the fetched module has its own version of statics. If you need to, you can pass parameters when you call the function pointer returned by fetch(). You do not get a new task.

    Question- Linking Multiple C/370 Source Files under CICS

    I am supporting a vendor who is converting a 4GL to run in an MVS/ESA CICS env't. He has successfully linked single C programs but is having difficulty when trying to link multiple C/370 source files. He has 24 programs, one MAIN. They are to be linked together as a single CICS transaction. Are there any special link options to be set? Stubs to include/not include? Does anyone have a sample of a procedure that he could use as a starting point?

    Answer

    Here are the general steps:

    For each piece of source:

    Question-What happens to malloc storage I did not free?

    I would like to understand what happens in the CMS environment if a C370 program does a malloc (or calloc) and does not subsequently free the storage before the program exits. I am vaguely aware of something called the "C environment" in which the C program runs. Does the breaking down of the C environment, upon program termination, free the storage that had been malloc'ed? Or is the storage still in use, from CMS point of view, and remain in use until the next IPL of CMS?

    Answer

    It gets freed by the C environment termination.

    Question- Bug in FOPEN?

    I have a program that was bombing miserably on certain user input. I've isolated the problem to the following snippet. Since I'm trying to fopen "*", this should cause fopen to fail, but instead it prints "Hi there" on the screen.

    #include <stdio.h>
    #include <stdlib.h>
    
    main(int argc, char * argv??(??))
    {
        FILE * handle;
        handle = fopen("*", "w");
        if (handle != NULL) {
            fprintf(handle, "Hi there\n");
            fclose(handle);
        }
        else {
            fprintf(stderr, "Error opening the file!\n");
        }
    }
    

    Answer

    According to the AD Cycle C/370 Programming Guide (1.1.1 p.120)

    If the first character in the filename string is an asterisk('*') and if the program is being run interactively, the terminal is opened; otherwise the remainder of the filename string is used as the file to be opened.

    ( under MVS Batch if filename=="*" 'this goes to SYSOUT on VM Batch if filename=="*" it goes to the job log ).

    This information is also found C/370 Programming Guide V2R1 pg 196-197 AD/Cycle C/370 Programming Guide V1R1M0 pg 118.

    This comes from the "General Information" Chapter of the Input and Ouput Section of the Programming Guide. This chapter can be quite helpful when attempting to start to use file I/O functions in C/370 and I would recommend to anyone that they read it.

    P.S. You would be suprised how common this mistake is ( at least I *hope* its common :-) one of the library developers had to show this section of the manual to me a year and a half ago:-)

    Question- const void *

    C/370 is non-ANSI-conforming in its handling of (const void *) in that it allows assignment to pointers to non-const-qualified types. For example, the following program unexpectedly compiles and produces the expected, given that it compiled, result 781:

        #include <stdio.h>
    
        static void f(const void *cvp)
        {
            int *ip = cvp;  /* should not be allowed */
            *ip = 781;   /* modifies const object without cast */
        }
    
        int main(void)
        {
            const int ci = 23;
            f(&ci);
            printf("ci = %d\n", ci);
            return 0;
    

    Answer

    Looks like all IBM C compilers fail in this regard: C/370, C Set/2 (but not C/Set++), and XLC. (Although xlc compiles it, running it on the RS6000 produces a plump and juicy core dump.

    This problem will be fixed and the next release of the C/370 compiler will complain about this assignment!! Thanks for highlighting this to us.

    Question- Compiler Bug??

    Is this a compiler bug???

    /***********************************************************/
    /* This is a program fragment demonstrating a bug(?) in the*/
    /* PARSER-error recovery of the 'C/370' compiler           */
    /***********************************************************/
    void A()
    {
      unsigned short i,j,k;
      unsigned char  Z Õ8þ = { '0','1','2','3','4','5','6','7'  );
     /*--------------------------------------------------------*/
     /* NOTE: The intentional error is in the               X  */
     /*       above line.  The initialization               |  */
     /*       data should be enclosed in '{-}' braces       |  */
     /*       Instead the final brace '}' is types          |  */
     /*       erroneously as a closing paren ')'           HERE*/
     /*  THE COMPILER CORRECTLY FLAGS THIS ERROR !!!           */
     /*  But also flags the following lines as errors       ...*/
     /*--------------------------------------------------------*/
     i= B( 15 );                  /* assume B is external...OK */
    
     if( i == 0 )
     {  j=5;
        k=7;
     }
     else
     {  if( i == 1 )
        {  j=7;        /* Syntax error on this line ..WHY ??   */
           k=55;
        }
        else
        {  if( i == 2 )
           {  j=8;     /* Another syntax error........WHY ??   */
              k=33;
           }
        }
     }
    }     /*END prog A */
    

    Answer

    Once the compiler sees a syntax error, it will either manufacture tokens to resynch itself, or throw away tokens until it sees something it can deal with. In either case, what the parser thinks it sees is not what you see, and all bets are off as to what sort of further errors you will get.

    Question- Number of records in MVS Dataset

    Can anybody tell me how to determine the number of records in an MVS dataset? I know the record size, and I thought I could seek to the end of file and do an ftell(), then divide by the record size. But ftell() is returning a rather large number (end of allocated space?).

    I'd like to know how many records are used. I could probably do this in assembler, but would like to stay with C if I can.

    Answer

    C/370 only gives you the byte offset from ftell() if you open a F, FB, or FBS dataset in Binary mode. Otherwise, you get an encoded offset. The encoded offset contains the relative block number and the relative byte within the block. Your method wouldn't work unless every record was full even if C/370 gave back offsets for V and U datasets (which it does not).

    Question- Return Code 33

    Does anyone know what return code of 33 from the cc command means?

    Answer

    The compiler (which itself is a C program) has detected that the library is of an earlier release level than the compiler itself.

    This could be caused by a wrong linked disk or someone has upgraded the compiler without upgrading the library.

    Question- Copyright Statements

    How can I generate copyright statements in front of my C code?

    Answer

    #pragma comment(copyright,"COPYRIGHT .......")

    Question- Set Locale in C/370

    Answer

    The EDC$S370 locale is set up at initialization time by your system programmer. The manual refers to the fact that the default LC_TOD information will be taken from this installed locale. In addition, note the fact that after initialization, changing EDC$S370 won't work. If you specify "", C/370 uses the EDC$S370 built into the library at initialization time and so does not perform an actual load of the one you have altered after installation.

    Regarding DBCS: the strcoll() routine does not support DBCS. The routine reads strings one byte at a time and would never know when it switched from double byte chars to single byte chars or vice-versa. The toupper() function likewise is not set up for DBCS since it expects the tolower() table to follow at a preset offset which only allows 256 chars + EOF. C/370 has created the wchar_t for manipulation of DBCS (see wcstr.h). Admittedly, there is DBCS functionality missing for things such as toupper(), isxxxxx.

    Question- File Buffers written to disk

    How can the program make sure that the file buffers for an output file are written to disk? We need to be able to recover this data in the event of a failure. We have tried fflush(), but this does not seem to work.

    Answer

    To make fflush() write the buffer to the disk, follow these rules:

      * with text files, write a new line, then fflush()
      * with binary files,
        - if F format, complete the record, then fflush()
        - if V format, just fflush() should do the trick
    

    Question- VB Dataset

    Problem, I have a VB dataset. Each record in the dataset is of variable length. So, I need to know how long each record is so I can do a fread(rec_array, RECORD_LENGTH,1,fp) That way I will get exactly one line in the read. But I am not sure how to get the RECORD_LENGTH. I went thru the C/370 books on C and there is nothing that even hints on how to do this?!?!? It tells me all about the VB datasets thought :-) Any ideas on how to do this in C or at least any places I can look for such information.

    Answer

    If you have the file opened for "type=record", you can specify a large value. Fread will read only one record and return the actual number of bytes it read.

    There is a paragraph on this in the CPI C ref for fread and fwrite commands.

    Question- Dataset Block Size???

    I am reading in a Variable Length Dataset record by record. I need to load an entire record into memory at one time. I really don't want to just allocate a buffer to be huge and hope that it will contain the longest line that could possibly exist in this file (which can be any number). Rather I would like to find the longest record length and malloc a block of memory of that size. Can I find this information out? I looked at the SVC99 service call but do not have the MVS manuals that explain how to get dataset characteristics. Is there any easy way to do this?

    Answer

    How about doing an fldata() on the open stream and using the __maxreclen component of the structure it returns? It's listed in the IBM C/370 Programming Guide.

    Question- Signal

    If anyone could answer the following on the use of signal, it would help me out no-end :

    Answer

    No, you cannot call the function with parameters. You are registering the function for when the error occurs. The function will be called with the signal number as the only argument. You could write a single piece of code that switched on the input argument to decide what to do and thus you could register the same address for each signal. The SIGABRT signal is issued only by raise(), i.e. it does not have a hardware counterpart. Note that abort() and assert() issue raise(SIGABRT) under the covers. If you are aborting, the return code in V2R1 is 1000. When running an MTF subtask, all handlers registered apply only to that subtask, i.e. you have a whole new environment and you are free to register handlers for that subtask; your other subtasks will not be affected.

    Question- fldata modeflag

    I wrote the following program and compiled it using the 2.1 version of the compiler:

    /*---------------------------------------------------------*/
    main()
    {
    
     FILE *fd;
     int   rc;
     char  fname  Õ100þ;
     fldata_t infostr;
    
     fd = fopen("file.dat", "w+");
     if (NULL == fd) {
        printf("error opening file\n");
        exit(0);
     } /* endif */
    
     rc = fldata(fd, fname, &infostr);
     if (0 != rc) {
        printf("error calling fldata\n");
        fclose(fd);
        exit(0);
     } /* endif */
    
     printf("mode returned from fldata: %d\n",infostr.__modeflag);
     printf("__READ: %d\n", __READ);
     printf("__WRITE: %d\n", __WRITE);
     printf("__APPEND: %d\n", __APPEND);
     printf("__UPDATE: %d\n", __UPDATE);
    
     fclose(fd);
    
    }
    /*---------------------------------------------------------*/
    

    Here's the output I got:

    /*-------------------------------*/
    mode returned from fldata: 10
    __READ: 1
    __WRITE: 2
    __APPEND: 4
    __UPDATE: 8
    /*--------------------------------*/
    

    This is not what I expected. With a program opening a file as "w+", shouldn't the mode returned include __READ or am I misunderstanding something here? Does __UPDATE mean that you have read access?

    Answer

    The output is correct. __UPDATE does mean that you have read access. You may have been mislead by the documentation. The Programming Guide says that a file opened "a+" will give the value __READ + __APPEND, which is, of course, wrong.

     "a+" should give the value __APPEND + __UPDATE;
     "w+" should give the value __WRITE  + __UPDATE,
                                             as in your example;
    
    We'll make sure the document gets fixed.

    Question- CSNAP and CDUMP

    Can anyone help me out as to how to use cdump and csnap. I've got the ctest.h include file and I've coded:

       csnap;
       cdump;
    

    and did a 'FILEDEF CEEDUMP DISK CDUMP OUTPUT A1', but I didn't get an output file??

    Answer

    You need to add the brackets to the calls, ie

       csnap();
       cdump();
    

    Without the brackets the C code means "evaluate the address of the csnap and cdump routines and throw them away.

    Question- Calculation Accuracy when using float type of double

    Why have OS/2 C and C/370 given a calculation off by one penny when using the float type of double?

    Answer

    The internal hardware representations of float types on these two platforms are different (see attached table). Although the initial precisions of double in the two platforms are the same, the error accumulates on a S/370 machine roughly 1.6 times faster that on a OS/2 machine. Also, since a float cannot be converted exactly into the hex base representation on S/370 precision may also be lost.

    If an application using double needs a precision close to 15 decimal digits, depending on the number of the intermediate steps involved in the calculation, OS/2 may potentially give a more accurate result. If the calculation is not on the margin of the precision, both platforms should give the same result.

    However, the long double on S/370 does provide a much better precision than that on OS/2.

              Table: Comparison of Float Type Representations
     -------------------------------------------------------------------------
     |                 |          OS/2 C          |          C/370           |
     |                 |--------------------------|--------------------------|
     |                 | Single | Double |Extended| Single | Double |Extended|
     |-----------------|--------|--------|--------|--------|--------|--------|
     |Base of Exponent |    2   |    2   |    2   |   16   |   16   |   16   |
     |-----------------|--------|--------|--------|--------|--------|--------|
     |    Range        | 10E-38 | 10E-308|10E-4932| 16E-65 | 16E-65 | 16E-65 |
     |                 | 10E+38 | 10E+308|10E+4932| 16E+63 | 16E+63 | 16E+63 |
     |-----------------|--------|--------|--------|--------|--------|--------|
     |  Conversion to  |Exactly |Exactly |Exactly |  not   |  not   |  not   |
     |    Decimal      |        |        |        |Exactly |Exactly |Exactly |
     |-----------------|--------|--------|--------|--------|--------|--------|
     | Width in bits   |   32   |   64   |   80   |   32   |   64   |  128   |
     |-----------------|--------|--------|--------|--------|--------|--------|
     |Init Precision in|    6   |   15   |   18   |    6   |   15   |   32   |
     | Decimal Digits  |        |        |        |        |        |        |
     |-----------------|--------|--------|--------|--------|--------|--------|
     |    Error        | slower | slower | slower | faster | faster | faster |
     |Accumulation Rate|  1.0   |   1.0  |   1.0  |   1.6  |   1.6  |   1.6  |
     |-----------------|--------|--------|--------|--------|--------|--------|
    

    Question- Realloc( ptr , 0 )

    When an attempt is made to realloc a block of storage to size of zero, a NULL is returned.

    Answer

    ANSI says: "If size is zero and ptr is not a null pointer, the object it points to is freed". Accessing this pointer later would result in the same undefined behavior you get when you access storage that has already been free()d. Usually this will be an exception.


    Missed our Premiere Edition

    If you did not get a copy of our Premiere Edition, just ask when you subscribe and we will be more than happy to send you a copy.


    A word from your editor

    If you didn't receive this newsletter mailed direct from IBM, and you would like regular hardcopy, then let us know. Mail in the reply form at the back with your request to join us, plus your full mailing address, and we'll add you to our mailing list, wherever you are. There's no charge for this newsletter. If you prefer, just put your business card in an envelope and mail or fax it to us at the address/phone number on the readers comment form.

    For the many of you sending in the reply forms with your comments, we may have the need to call you to discuss your comments further. It's a great help if you include your phone number. Thanks!


    Coming Soon

    Well, that's all the bits we can squeeze in for now. In future issues, we'll discuss some performance tips, porting tips and answer some more of your questions. Thanks for reading and please let us know what you think of this newsletter.

    +--------------------------------------------------------------------+
    

    This newsletter was produced by the C/370 Planning department of the IBM Programming Systems 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 . IBM Canada Ltd., a related company, is a registered user.

    This newsletter was created and marked for processing using IBM BookMaster(TM) (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 1993.

    In Canada - © Copyright IBM Canada Ltd. 1993. +--------------------------------------------------------------------+


    C/370 Compiler News Volume 1 Number 2 June/93 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, or hand it into an IBM office for forwarding.

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

    C/370 Compiler News Volume 1 Number 2 June/93 Issue

    Reader's Comment Form




    Footnotes:

    ( ) Products marked (TM) are trademarks or registered trademarks of IBM Corporation