1

I have a block of code that I want to #include in my z/OS Metal C program, it works fine when it's just part of the program, but when I put it into a .h file and #include it, the code won't compile.

I have successfully gotten this code to work without #include. I'm sure I'm overlooking something having to do with #include...

This code works:

    #pragma margins(2,72)                                                  
    *#if 0!=0                                                              
    Test     DSECT                                                         
    Test@    DS A                                                          
    TestINT  DS F                                                          
    TestChar DS C                                                          
     .ago end                                                              
    *#endif                                                                
    *struct Test {                                                         
    *  void *Test1;                                                        
    *  int TestInt;                                                        
    *  char TestChar;                                                      
    *};                                                                    
    *#if 0!=0                                                              
    .end                                                                   
     MEND                                                                  
    *#endif                                                                
     #pragma nomargins

Giving compiler output that looks like this:

      207       |#pragma margins(2,72)                                            
      207       +                                                                 
      208       |#if 0!=0                                                         
      214       |#endif                                                           
      215       |struct Test {                                                    
      216       |  void *Test1;                                                   
    5650ZOS V2.1.1 z/OS XL C                          'SSAF.METALC.C(CKKTHING)'   


                                              * * * * *   S O U R C E   * * * * * 

     LINE  STMT                                                                   
                 *...+....1....+....2....+....3....+....4....+....5....+....6....+
      217       |  int TestInt;                                                   
      218       |  char TestChar;                                                 
      219       |};                                                               
      220       |#if 0!=0                                                         
      223       |#endif                                                           
      224       |#pragma nomargins                                                                                                    

But, when I put the code into an #include file like this:

    EDIT       SSAF.METALC.H(CKKTEST)
    Command ===>                     
    ****** **************************
    000001 *#if 0!=0                 
    000002 Test     DSECT            
    000003 Test@    DS A             
    000004 TestINT  DS F             
    000005 TestChar DS C             
    000006  .ago end                 
    000007 *#endif                   
    000008 *struct Test {            
    000009 *  void *Test1;           
    000010 *  int TestInt;           
    000011 *  char TestChar;         
    000012 *};                       
    000013 *#if 0!=0                 
    000014 .end                      
    000015  MEND                     
    000016 *#endif                   
    ****** **************************

and include it in my Metal C program:

    EDIT       SSAF.METALC.C(CKLTHING) - 01.00
    Command ===>                              
    000205 #include"ckkprolg.h"               
    000206                                    
    000207 #pragma margins(2,72)              
    000208  #include"ckktest.h"               
    000209  #pragma nomargins                   

I get a bunch of error messages:

      205       |#include"ckkprolg.h"               /* Include assembler macros needed                        
      206       |                                      for Metal C prolog and epilog  */                      
      207       |#pragma margins(2,72)                                                                        
      207       +                                                                                             
      208       |#include"ckktest.h"                                                                          
    *=ERROR===========>     CCN3275 Unexpected text 'struct' encountered.                                     
    *=ERROR===========>     CCN3166 Definition of function Test requires parentheses.                         
    *=ERROR===========>     CCN3275 Unexpected text 'void' encountered.                                       
    5650ZOS V2.1.1 z/OS XL C                          'SSAF.METALC.C(CKLTHING)'                    10/04/2019 


                                              * * * * *   S O U R C E   * * * * *                             

     LINE  STMT                                                                                               
                 *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9...
    *=ERROR===========>     CCN3045 Undeclared identifier Test1.                                              
    *=ERROR===========>     CCN3275 Unexpected text 'int' encountered.                                        
    *=ERROR===========>     CCN3045 Undeclared identifier TestInt.                                            
    *=ERROR===========>     CCN3275 Unexpected text 'char' encountered.                                       
    *=ERROR===========>     CCN3045 Undeclared identifier TestChar.                                           
    *=ERROR===========>     CCN3046 Syntax error.                                                             
    *=ERROR===========>     CCN3273 Missing type in declaration of theESTAEXStatic.                           
      209       |#pragma nomargins                                                                            

  • I am not sure what you are hoping to achieve, this block of code even when compiled clean produces an assembler source file which has an empty CSECT and the entire block of code is commented out. – Milos Lalovic Oct 07 '19 at 20:41

1 Answers1

0

The include file is missing #pragma margins. Since it is a file level directive, it needs to be present in each source file. Please see IBM Knowledge Center, which says, "The setting specified by the #pragma margins directive applies only to the source file or include file in which it is found. It has no effect on other include files."

Nicole Trudeau
  • 678
  • 3
  • 8
  • Ok, so the point here is to be able to put the assembler DSECT and C struct into the same dataset or file and use macro logic to keep the compiler from stumbling on the assembler statements and the assembler from stumbling on the compiler statements. Having to put the #pragma into the included file makes this approach seemingly untenable. Is there a valid "first line" that I can put into a macro that is acceptable to both the assembler and the compiler that allows me to start the logic to keep the statements separated? – Scott Fagen Oct 07 '19 at 17:42
  • Instead of the `#pragma`, you can also use the [`MARGINS` compiler option](https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.4.0/com.ibm.zos.v2r4.cbcux01/margcop.htm?sc=SSLTBW_latest), which will apply to both the main source file and the include file, saving you from having to edit multiple files. Does that help? – Nicole Trudeau Oct 07 '19 at 19:03
  • Maybe...I'll give that a try. – Scott Fagen Oct 08 '19 at 17:49
  • Nicole, it does seem to help, now I can put a * in column 1 to prevent the assembler from dealing with a compiler only statement, AGO and MEND to control what the assembler sees and not, and use #if and #endif to control what the compiler sees and not. That all being good, will this work with the "standard" .h files that are included to make for a working C or Metal C program, e.g. metal.h, string.h? If they start in column 1, then they won't work correctly, right? I looked at /usr/include/metal and some start "beyond column 1," but others don't. – Scott Fagen Oct 09 '19 at 15:23
  • I can confirm that IBM says they put #pragma statements in their .h files. – Scott Fagen Oct 11 '19 at 16:16
  • Thanks for circling back Scott. All system header files have their own #pragma margins which ensures that regardless of the `MARGINS` option or #pragma margins in your source, the header files are processed correctly. [Here's a link](https://www.ibm.com/developerworks/community/forums/html/topic?id=377ab4bb-7a85-4bc6-bcf9-4c27bb900648) to this question posted on IBM's forum. – Nicole Trudeau Oct 15 '19 at 21:08