Welcome to the Premiere 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

March 1993 Volume 1 Number 1


Table of Contents

Welcome to the Premiere Issue of the C/370 Newsletter

  • Subscribe Now
  • In This Issue
  • Who the heck are we?
    C/370 Version 2 Features
  • New Features Available in the MVS, VM and VSE Environments
  • New Features Unique to the MVS and VM Environments
  • Features Unique to the VSE Environment
  • Exploring The CHECKOUT Option
  • The Suboptions
  • Want more info.......
    C/370 Performance Hints
  • Input/Output Hints and Tips
  • Loops and Control Constructs Hints and Tips
  • You ask, we answer
    A word from your editor
    Coming Soon
  • Reader's Comment Form

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

    You know that compilers are not flashy software and that mainframes are dinosaurs. So who would want to read a newsletter about a mainframe compiler?

    We think you will.

    The goal of this newsletter is to provide a practical forum to answer your questions, update you on the latest news on C/370 and provide you with information that will allow you to get the most out of your C/370 Compiler. The key word here is practical. We want to provide you with concise information that you can use without reproducing the entire set of manuals.

    We'll tell you more about ourselves later, but for now, our intent is to share with you some hints and tips that we have uncovered through our experience with C/370 and through our numerous contacts with various customers.

    Subscribe Now

    If you want to continue receiving future issues of this newsletter, please subscribe. Currently, our plan is to publish a newsletter every quarter. There's no charge (REALLY!); just fill in the Reader's Comment Form at the back of this newsletter and send it to us via fax or mail. If you know of others who would benefit from receiving this newsletter, please include their names as well. Better still, feel free to copy this newsletter and pass it on to your colleagues.

    In This Issue

    Here goes....


    Who the heck are we?

    We are the people who develop and maintain C/370 and AD/Cycle(TM) C/370. We're part of the Language Technology Centre(LTC) of the IBM Programming Systems Toronto Laboratory. Yes, we're located in Toronto, Canada, home of the World Series Baseball champions, the Toronto Blue Jays.

    The LTC has over 300 people working on the development of compilers and compiler tools for all IBM Platforms, from C/Set2(TM) on OS/2(TM) , through C++ and Fortran on the RISC/6000(TM) , the AS/400(TM) where we have a complete suite of languages, including RPG and COBOL, to C/370 on System/390. ( )

    Current C/370 products are:

    Please note that C/370 Compiler Version 1 was withdrawn from marketing effective August 30, 1991. C/370 Library Version 1 will be withdrawn from marketing effective September 30, 1993. Both the C/370 Library and Compiler Version 1 will be withdrawn from service effective December 31, 1993.

    As for the C/370 product itself, one thing you may not realize is that it was created for developers by developers, and we're our own customers - we use it every day, day in, day out. Hundreds of products being developed in IBM all across the world, those for internal use only and those intended for sale, depend on C/370. If something doesn't work for you, it doesn't work for us, either. Thus we have a very selfish interest in making our product the best we can, and fixing anything that doesn't work!


    C/370 Version 2 Features

    New Features Available in the MVS, VM and VSE Environments

    New Features Unique to the MVS and VM Environments

    Features Unique to the VSE Environment


    Exploring The CHECKOUT Option

    Did you ever finish coding a program and wonder whether you declared any variables that you ended up not using, coded anything that was not portable, or included the correct #include files? If you answered yes to any of the above, then the CHECKOUT option is for you. The CHECKOUT option was created to aid C programmers in debugging their programs by generating informational warning messages indicating possible programming errors.

    The CHECKOUT option has several suboptions so that you can pick and choose the type of messages that you would like to generate. The CHECKOUT suboptions can be specified on the command line or by #pragma options. You can also suspend and resume the CHECKOUT processing for certain pieces of code by using #pragma checkout. These features make the CHECKOUT option flexible and easy to use.

    The Suboptions

    Each suboption controls several different warning messages that can be produced if certain code fragments are encountered. These code fragments may potentially cause errors during execution of the code.

    A description of each suboption and an example of code that would generate a warning message for the respective suboption are given below. Although the samples below show one example per suboption, there are numerous situations where these messages will be generated. Note that the bold Suboption is the default and the capitalized letters are minimum command shortforms.

    1. ACcuracy|NOACuracy

      Messages concerning assignments of long values to variables that are not long.

      The following code will produce a warning regarding the lost precision when assigning the long int k variable to the short int j variable.

         short int j = 1;
         long int k = 2;
      
         j = k;
      
      

    2. ENum|NOENum

      Messages regarding the usage of enumerations.

      For a switch statement where the switch control expression is an enum, the case label values must be members of the enumeration. Therefore, if one of the labels is not a member of the enum, a warning message will be generated. The following code fragment would generate a warning stating that the case label 34 is not a member of the enumeration.

      enum {red, blue, green } color = red;
      switch (color)
      {
         case red:    /* These are valid    */
           break;
         case blue:   /* case label values  */
           break;
         case 34:     /* This is not a      */
           break;     /* valid case label   */
      }
      

    3. EXtern|NOEXtern

      Messages regarding variables that have external declarations, but are never used.

      The messages issued by this option would highlight any variables or functions that are declared or initialized but never used. The following code would generate a warning message stating that the static variable newvar has been set but not referenced.

      main()
      {
        static int newvar = 4;
        printf("Hello\n");
      }
      
      

    4. GEneral|NOGEneral

      Messages regarding basic diagnostics.

      There are several messages that fall into this category. Some of examples of these are: statements or expressions that have no effect, variables that are set but never referenced, variables that are not initialized, assignments found in control expressions, suspect type conversions or use of bitwise operators and unreachable code. The best way to see the results from this option is to try it out and see what is generated on some of your own code.

      The following example shows a common error in C programming. Often an assignment statement is accidentally coded instead of a comparison statement. The following code generates a warning regarding the assignment in the control statement.

      int i = 3;
      if ( i = 3 )   /* rather than ( i == 3 ) */
         printf("Hello\n");
      
      

    5. Goto|NOGoto

      Messages concerning the appearance and usage of goto.

      A Goto statement should not be located in an inner block of code such as a loop; hence the following piece of code would generate a warning stating that an unstructured goto statement has been encountered.

      goto labl;
      for (;;)
      {
          int a = 55; /* The label is inside a loop */
          labl: ;     /* and after the variable     */
      }               /*    initialization          */
      

    6. Init|NOInit

      Messages regarding variables which are not explicitly initialized.

      There are several warning messages that can be generated for different types of variables that are not initialized properly. The following code would generate a message stating that the variable i may not have been set before it was first referenced.

      int i, a;
      a = i;
      
      

    7. PARm|NOPARm

      Messages about function parameters which are not used.

      The following code will produce a warning stating that the parameter argc is not used.

      main(int argc) {
          printf ("hello!\n");
      }
      
      

    8. PORt|NOPORt

      Messages concerning non-portable usage of the C language.

      Due to the different storage of signed numbers on various platforms, a warning regarding actions that will effect the sign are generated. The following example would generate a warning regarding a right shift operator being applied to the signed variable shiftit.

      signed int shiftit = 1, shifted = 2;
      shifted = shiftit >> 3;
      
      

    9. PPCheck|NOPPCheck

      Messages about all preprocessor directives.

      One message produced by this option will inform you if #include files have been included more than once. The following code issues a warning message regarding the inclusion of stdio.h twice.

      #include <stdio.h>
      #include <stdio.h>
      
      main() {
      printf("hello\n");
      }
      
      

    10. PPTrace|NOPPTrace

      Messages about Preprocessor activities

      This option will produce preprocessor trace messages regarding code that expands trigraphs, undefines macros, duplicates definitions for macros, and other preprocessor activity For example, the following code would generate warnings indicating the beginning and ending of the #if and #endif directives.

      #if 0
         int i;
         char j;
      #endif
      
      

    11. TRUnc|NOTRUnc

      Messages regarding variable names that are truncated by the compiler.

      External variables are limited to 8 characters. The following code will generate a warning message indicating that the variable abcdefghijklmnopqrstuvwxyz has had its name truncated.

      int abcdefghijklmnopqrstuvwxyz = 1;
      main()
      {
          abcdefghijklmnopqrstuvwxyz = 3;
      }
      

    12. ALL

      This option will generate all CHECKOUT warning messages.

    13. NONE

      This option will turn off all CHECKOUT warning messages.


    Want more info.......

    SC09-1384
    IBM C/370 Programming Guide

    SC09-1356
    IBM SAA AD/Cycle C/370 Programming Guide

    C/370 Performance Hints

    This regular feature of our newsletter will discuss a few ways to help write more efficient C programs suitable for any machine, as well as the S/370/390 architecture, and will discuss some performance features of the C/370 Compiler and Library. This issue will concentrate on I/O Performance as well as Loops and Control Constructs Performance. Subsequent issues will have some hints and tips on Built-in Library Functions, Declarations, Library Extensions, as well as the Optimizer mentioned earlier.

    Input/Output Hints and Tips

    Loops and Control Constructs Hints and Tips


    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-Trouble Reading DD concatenation

    I have been trying to read the following DD concatenation without success.

    //*------------------------------------------
    //PARMS DD DISP=SHR, DSN=A433021.PIP.CNTL(JOB1)
    //      DD *
          {data}
    /*
    //*------------------------------------------
    

    Job step running the C program with the concatenation above always ends with a 013-BC abend. Just the instream works fine and so do jobs with just the dataset or a concatenation of datasets. Have tried both sequential and partitioned datasets in combination with the instream data. LRECL, BLKSIZE, and so on are the same.

    Answer

    C/370 treats all concatenations as LIKE concatenations. Thus, when you move from one dataset to the next, DPF handles the switch using the DCB used to access the first dataset. When you access a sequential DASD dataset first, C/370 opens it with the abilitity to seek (NOTE/POINT macros in the DCB). When you switch over from the DASD dataset to the INLINE dataset, the DCB in now inappropriate since it has the NOTE/POINT macros set up. If you use the NOSEEK option on your fopen() call, this will prevent that problem. The option tells C/370 not to set up the NOTE/POINT macros in the DCB.

    Question-read(),write(),open(), close() and file descriptors

    I have looked through the C/370 manual and I can not find any references to these routines (except for network communication).

    Are these routines supported by C/370? Are only the 'fopen', fclose, fprint, etc' routines supported for file access.

    Answer

    Sorry. C/370 supports the ANSI C library calls. These routines are not part of ANSI C. They are UNIX system calls which some other products emulate.

    Question-ISPF Interface with C

    I looked at the examples in the C reference manual for Version 2 Release 1.0. I typed it in exactly (see below) and could not get it to link. It cannot find the ISPLINK to link in. What am I doing wrong?

      #include <stdio.h>
      #include <stdlib.h>
    
      #pragma linkage(ISPLINK,OS)
      extern ISPLINK();
      intern rc;
      int main(void)
        {
          rc=ISPLINK("DISPLAY",ISPFEG@","");
        }
    

    Answer

    ISPLINK is a stub module shipped with ISPF. You will have to add the ISPF load library (SYS1.ISPLOAD) to your SYSLIB to resolve the link problem.

    Question-Linking "longname" text decks

    I'm trying to create a module from two C text decks, main and sub1.

    Here's how I compiled main: cc main

    Here's how I compiled sub1: cc sub1 (lo

    sub1 was compiled with the longnames option because it contains references larger than 8 characters (not for reentrancy).

    I know I have to use the pre-linker and CMOD but I must be missing something.

    Answer

    It is not advisable to compile 'some' of your modules with longname and some without. If you want longname support, compile everything with the longname compile option, then prelink it all together.

           CC main (longname
           CC sub1 (longname
           CMOD main sub1 (CPLINK
    

    Question-Internal Floating Point Representation Differences

    I am sending / receiving floating point data between C/370 and VS COBOL II languages. I am finding differences in the internal representation. For example, the number 1234.32 is represented internally in C/370 float as x'434D251E' (1234.319824) and in in VS COBOL II Computational-1 as x'434D251F' (1234.320068).

    Should these internal values be the same since the architecture is 370? I am having problems comparing the values after sending from one language to another.

    Answer

    Note that 1234.32 has type 'double' in C which is 8 bytes on S/370. If in your C code, you assigned it to a float, then the 8 bytes are truncated to 4 and you lose significance. You should use 1234.32F which has type float and should have the correct value.

    Another thing to be aware of when passing float from C to COBOL is that float arguments get converted to double before being passed. This is done by padding with 4 bytes of zeroes which changes the value.

    Our recommendation is to use double in C and the equivalent 8 byte type in COBOL. Then you need not worry about suffixes on literals or conversions on function calls.

    In addition, please be aware that there is a problem with floating point conversions in C/370 V1, which may explain the difference you're observing. It was fixed in C/370 V2R1 by APAR PL78997, PTFs UL94889 (MVS) and UL94891 (VM).

    Question-Memcpy() VS SSCANF() Performance

    I have found that performing memcpy() instead of sscanf() function makes a significant difference in performance. Why is this so?

    Answer

    memcpy() is a builtin function. When the compiler generates code, it does not generate a function call, buy instead generates S/370 instructions to perform the task. This saves time. In addition, the sscanf() function is quite complex due the functionality it provides. We would expect you to see better performance with memcpy() even if the builtin function is not used. In order to get the builtin function you must include <string.h>.

    Question-Where can we find what a RC=1 means from FERROR following a FWRITE?

    I am trying to update a record in place after the file is opened with type rb+. The read is successful but the FWRITE following gets an error, FERROR has a RC=1. The file is a one 9K record file. What does RC=1 indicate and where can we find what the return codes mean?

    Answer

    The ferror() function is documented in the SAA CPI C Reference. A non-zero value indicates that an error has occurred. A return value of zero would indicate that no error had occurred. For further information on what kind of error occurred, there are two places to look:

    Are you trying to perform an update by calling a write function immediately after a read operation ? If so, this would explain why the write is failing. The ANSI C standard specifies that write operations may not follow a read operation without an intervening fflush() or reposition operation except when a read which encounters EOF may be followed by a write (this exception is part of the ANSI standard. This write will extend the file, not update it).

    Question-QXXZTOI Port to MVS

    I am in the process of porting C/400 code to C/370. After getting a successful compile, my link step failed due to module QXXZTOI missing. QXXZTOI is a C/400 library function which converts a zoned decimal value to an int value. I've looked through the C/370 library and have not found anything similar. Is there a similar function in C/370 that I have overlooked?

    Answer

    Unfortunately, C/370 does not have anything like this. The only options we can think of are calling (A) assembler or (B) COBOL to do the work for you.

    Question-Internal Error

    Got the following message and don't know what it is.

     INTERNAL ERROR EDC0001: INTERNAL COMPILER ERROR AT PROCEDURE T-PHASE
    

    Answer

    This message means that there is a bug in the compiler. There is probably nothing wrong with your code. Report it to IBM.

    Question-Problem with long function names

    The program below when compiled produces the following messages.

     EDC0244 External name very_long_name_problem
             has been truncated to VERY_LON
      EDC0248 External name VERY_LON cannot be
             redefined
    
      #include <stdio.h>
      void very_long_name(void)
      {
        printf("This is not the main routine\n");
      }
      void very_long_name_problem(void)
      {
        printf("This is not the main routine\n");
      }
      main(void)
      {
      very_long_name()
      very_long_name_problem()
      printf("This is the main routine\n");
      }
    

    Answer

    If the functions are internal (not to be exported outside the compilation unit), then make them "static" and you should have no problems.

    If you want long external names, you must get C/370 V2R1 or AD/Cycle C/370 1.1 and use the LONGNAME Option.

    Question-Problem with QSORT

    We just converted from the 1.? to 2.1 "C" compiler. The following code no longer works. Can QSORT be used to sort structures like this? I assume I've made a typecasting error but don't see how to fix it.

    typedef struct {
                    char names??(19??);
                    char types??(9??);
                    short lengths;
                    short scale;
                    short location;
                   } table_data;
    ***** following is section from main and error message *******
    
     qsort( table_info, count, sizeof( table_info??(0??) )
            , comp_cols );
    ***********************ERROR**********************************
    a-EDC0322 Type of the parameter cannot conflict with previous
              decl
    a-EDC0141 Prototype has type pointer to constant void .
    a-EDC0147 Argument has type pointer to structure with no tag.
    
    int comp_cols( table_data *info1, table_data *info2 );
    int comp_cols( table_data *info1, table_data *info2 )
    {
       short compare;
       compare =  strcmp( info1->names, info2->names );
       if( compare == 0 )
       {
          if( info1->location > info2->location )
            return( 1 );
          if( info1->location < info2->location )
            return( -1 );
       }
       else
         return( compare );
    }
    

    Answer

    Actually, it's not a bug. The compiler is complaining that the argument type doesn't *exactly* match the parameter type. For qsort(), the protoype is:

      void     qsort (void *, size_t, size_t,
                      int (*)(const void *,
                                    const void *));
    
    
    where the final parameter is a 'pointer to function (taking two const void* arguments) returning int'. The function pointer you tried to pass was a 'pointer to function (taking two table_data* arguments) returning int.' ANSI C requires that for two functions to be compatible, their parameter lists must be exactly identical. In this case, they are not. The solution, in this case, is to cast the 'comp_cols' function to be the correct type:
     typedef int (*qsort_compare_fn)(const void *, const void *);
    
     qsort( table_info, count, sizeof( table_info??(0??) ),
          (qsort_compare_fn)comp_cols );/* <-- inserted cast!!! */
    

    C/370 V1 missed this error.

    Question-Macros

    My source dataset is FB 80 and I need a macro to extend (with the backslash continuation) over 80 bytes. Is there anyway to do that?

    Answer

    You just said it...use the continuation sequence.

       #define LONG_MACRO "this macro will be very very  \
       very very very very very very very very very very \
       very very very very very very very very very very \
       very very very very very very very very very very \
       long"
    

    Be aware that for a FB 80 source file, the default margins and sequence columns are MARGINS(1, 72) SEQUENCE(73, 80). This means that columns 73-80 of your source will be ignored. Make sure that nothing of significance appears in these columns (including the continuation sequence!), or compile with NOMARGINS NOSEQUENCE.

    Question-Use of fetch and release to load Fortran subroutines dynamically

    I am trying to use the C/370 facility fetch to load and execute a FORTRAN subroutine in the manner which is described in the manual C/370 Users Guide. The systems is MVS/ESA. The problem is that when the main C code tries to load the subroutine I get an S806-04 abend. The dump says that #VSFTASK has failed during load and that the library has not been initialized.

    Its not clear to me what exactly is going wrong. Could it be something to do with the initialization of the FORTRAN environment? When I change the SUBROUTINE to a main program and use system instead of fetch everything works. In the long term I need to pass arguments so the latter is not a working solution.

    Answer

    The problem you are encountering is that the VS FORTRAN library is not being initialised and #VSFTASK is the symptom. Page 331 of the IBM C/370 Programming Guide, SC09-1384 indicates that C handles starting the FORTRAN environment. You do have to identify the function as a FORTRAN function with a pragma linkage directive.

    Queston-Initializing HEX

    I'd like to initialise an eight byte field to the hex value X'FFFFFFFFC3C400C5'. How would I do this in C?

    Answer

    char bytes??(8??)="\xff\xff\xff\xff\xc3\xc4\x00\xc5";

    Question-# line Directives from PPONLY Preprocessor Option

    When I am processing a file with the PPONLY preprocessor option, there should be a # line directives that are automatically generated.

    Currently, I don't see these # line directives in my output (SYSUT10). Is there a flag or something I need to do to get them?

    Answer

    PPONLY(*) generates #line directives. The purpose is to allow the output to be recompiled/reprocessed. For this reason the output is not folded (after all that would invalidate the #line directives). Your output dataset should be set up to accommodate long records which may be created by macro expansion.

    Question-Writable static point is zero in fetched function

    After some experimentation we have discovered some behavior we do not understand.

    In all of the following cases the calling module is doing a fetch("x") and then calling the function returned by fetch. In all cases the C code for the fetched module is compiled RENT and prelinked, and the entry point for the fetched module is CEESTART. We are using C/370 V2R1M0.

    Case 1:

    The fetched module has a #pragma linkage(X,fetchable) and defines the function X. The load module is named Y and given an alias of X. The fetch returns successfully, but when function X attempts to write to its writable static a protection exception is generated. The writable static pointer is 0 on entry to X.

    Case 2:

    The fetched module has a #pragma linkage(X,fetchable) and defines the function X. The load module is named X and given an alias of Y. Everything works fine. Function X can write to its writable static.

    Case 3:

    The fetched module has a #pragma linkage(Z,fetchable) and defines the function Z. The load module is named Y and given an alias of X. Again everything works fine. Function Z, when called by using the function pointer returned by fetch("X"), can write to its writable static.

    Can anyone explain why Case 1 fails? Any help would be appreciated.

    Answer

    You are creating an alternate entry point using the ALIAS statement.

    If you look at the Linkage Editor and Loader's User's Guide:

    "An entry point other than the main entry point may be specified with an ALIAS control statement. The symbol specified on the ALIAS statement must be defined as an external symbol in the load module. Any reference to that symbol causes execution of the module to begin at that point instead of at the main entry point."

    Because X is an external symbol and you chose to ALIAS it, it became an additional entry point. When you fetched it by that name, X was the entry point and C/370 did not attempt to find the writable static information since it only does so if CEESTART is the entry point.

    Question-FORTRAN/C Interface

    We have been testing interlanguage interfaces. We have discovered a situation which operates on other vendor platforms, but is failing on VS FORTRAN 2.5 with C/370 2.1.

    The code is rather tricky and probably violates some ANSI standards.

    Basically, the FORT main calls C to allocate storage. Then it calls C again which goes back to FORT to fill the array. Upon the return to C from the FORT C2F, the PRINTF shows the array contains zeroes. All the PRINTs until that point look OK.

            program ftest
    c
            parameter (LWORD=4)
    c
            call csub (iadr, 20*20*LWORD)
            print *,' after call to sub, iadr = ', iadr
            call f2c2f( iadr )
            end
    
            subroutine c2f (arr)
            real arr (20, 20)
            i = iadr (arr)
            print *,' address of arr = ', i
            do 10 j = 1, 5
               do 10 i = 1, 5
                  arr(i,j) = i + (j-1)*5
                  print *,' arr(i,j) = ', arr(i,j)
       10   continue
            return
            end
    ********************************* C CODE ******************************
    #pragma linkage (csub, FORTRAN)
    #pragma linkage (iadr, FORTRAN)
    #pragma linkage (f2c2f, FORTRAN)
    #pragma linkage (c2f, FORTRAN)
    
    csub (int *iadress, int *bytes)
    {
       printf ("in csub before calloc, *iadress = %d, *bytes = %d\n",
               *iadress, *bytes);
       *iadress = calloc (*bytes, 1);
       if (*iadress == 0L)
          printf(" Error in csub after malloc.\n" ) ;
    
       printf("in csub after calloc, *iadress = %d, *bytes = %d\n",
              *iadress, *bytes);
    }
    
    f2c2f (int *arg1)
    {
       int     i, j ;
       float   *A ;
    
       printf ("\n\nMLH Inside f2c2f, *arg1 = %d\n\n\n", *arg1);
    
       c2f (*arg1) ; /* Pass back to FORTRAN with a level of indirection */
    
       A = (float *) (*arg1);
    
       for (j = 0; j < 5; j ++)
       {
          for (i = 0; i < 5; i ++)
          {
             printf(" arg1 ??(j??) ??(i??) = %f\n", A ??(j * 20 + i??));
          }
       }
    }
    
    int iadr (int *v)
    {
       printf ("\n\nMLH Inside iadr, *v = %d\n\n\n", *v);
       return ((int) v);
    }
    

    Answer

    The problem is that you are passing an integer from FORTRAN to C, and what you are storing in there is a pointer to an int, you need an extra level of indirection.

            program ftest
    c
            parameter (LWORD=4)
    c
            call csub (iadr, 20*20*LWORD)
            print *,' after call to sub, iadr = ', iadr
            call f2c2f( iadr )
            end
    
            subroutine c2f (arr)
            real arr (20, 20)
            i = iadr (arr)
            print *,' address of arr = ', i
            do 10 j = 1, 5
               do 10 i = 1, 5
                  arr(i,j) = i + (j-1)*5
                  print *,' arr(i,j) = ', arr(i,j)
       10   continue
            return
            end
    *****************************************************************
    
    #pragma linkage (csub, FORTRAN)
    #pragma linkage (iadr, FORTRAN)
    #pragma linkage (f2c2f, FORTRAN)
    #pragma linkage (c2f, FORTRAN)
    
    csub (int **iadress, int *bytes)  /* Indirection Added */
    {
       printf ("in csub before calloc, *iadress = %d, *bytes = %d\n",
               *iadress, *bytes);
       *iadress = (int *) calloc (*bytes, 1); /* Indirection Added */
       if (*iadress == 0L)
          printf(" Error in csub after malloc.\n" ) ;
    
       printf("in csub after calloc, *iadress = %d, *bytes = %d\n",
              *iadress, *bytes);
    }
    
    f2c2f (int **arg1) /* Indirection Added */
    {
       int     i, j ;
       float   *A ;
    
       printf ("\n\nMLH Inside f2c2f, *arg1 = %d\n\n\n", *arg1);
    
       c2f (*arg1) ; /* Pass back to FORTRAN with a level of indirection */
    
       A = (float *) (*arg1);
    
       for (j = 0; j < 5; j ++)
       {
          for (i = 0; i < 5; i ++)
          {
             printf(" arg1 ??(j??) ??(i??) = %f\n", A ??(j * 20 + i??));
          }
       }
    }
    
    int iadr (int *v)
    {
       printf ("\n\nMLH Inside iadr, *v = %d\n\n\n", *v);
       return ((int) v);
    }
    


    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. Yes, wherever you are...from Argentina to Zaire, if you have a mail service, we'll mail you our newsletter.

    For the many of you sending in the reply forms with your comments, we've 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 of your questions. Thanks for reading and please let us know what you think of our first 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 © IBM Corporation 1993. +-------------------------------------------------------------------+


    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 Editor, C/370 Newsletter, Box 2316. Thanks.




    Footnotes:

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