I agree with these comments. As I told my manager, the z/OS upgrade did not break this program, it discovered the flaw :)
I rarely get a chance to thank the people on this list for their help and insight these many years. Because of you, I was able to resolve this "issue" in 3.5 hours from the time I learned of it. Thank you once again. I hope I can be as helpful, sometime in the future. > -----Original Message----- > From: IBM Mainframe Discussion List [mailto:[email protected]] > On Behalf Of Bernd Oppolzer > Sent: Monday, June 23, 2014 4:50 PM > To: [email protected] > Subject: Re: C program stopped working with z/OS 1.13 on production rollout > of z/OS 1.13 :( > > Some remarks: > > - C auto variables, as in this case, are not initialized on entry to a > function. > That is, the content is unknown, maybe zero or any other value. > The use of this uninitialized variable is a program error and did not show up > on the prior releases of z/OS, as it seems. It is not ok to blame the new > release of the OS for this ... which is done sometimes. The program is in > error > (has always been) and has to be fixed. > > - the z/OS compiler has options to do initialization of auto variables, AFAIK > (at > least I know that the PL/1 compiler has such options), but I do not recommend > to use such options, because it generates performance problems > > - some smart compilers generate warnings, when uninitialized variables are > used. To do that, static analysis of the program flow has to be done to some > extent; this works more or less good, so these warnings are sometimes > correct, sometimes not. If the compilers I use support such warnings, I would > suggest to switch them on (the PL/1 compiler does this, and it saved me from > lots of errors in the last years). > > Kind regards > > Bernd > > > > Am 23.06.2014 21:53, schrieb Gibney, Dave: > > Thank you, I only rarely C. Changing these two lines to have the zero > initialization > > int in_cnt=0, out_cnt=0; > > int incrmt=0, inc=0, blnk_cnt=0, recout_siz=0, FEOF=0; > > > > returned the program to working. And I know the was some re-arranging of > where initial memory would be allocated between 11 and 13. > > > >> -----Original Message----- > >> From: IBM Mainframe Discussion List [mailto:IBM- > [email protected]] > >> On Behalf Of Sam Siegel > >> Sent: Monday, June 23, 2014 12:45 PM > >> To: [email protected] > >> Subject: Re: C program stopped working with z/OS 1.13 on production > >> rollout of z/OS 1.13 :( > >> > >> Several variables, including FEOF, are not explicitly initialized to 0. > >> The program appears to set FEOF to 1 only when there is an error > >> opening either of the DDs. > >> > >> There may be residual data on the stack which is setting FEOF to a > >> non-zero value. > >> > >> I don't think the C standard requires the compiler or runtime to > >> ensure any particular value to non-initialized variables. > >> > >> Sam > >> > >> > >> On Mon, Jun 23, 2014 at 12:12 PM, Gibney, Dave <[email protected]> > wrote: > >> > >>> I have a C program, written by someone long gone, last complied in > >>> 2004 or so. Running under z/OS 1.13, it reports reading/writing zero > >> records. > >>> STEPLIB of CEE.SCEERUN from z/OS 1.11 returns it to its previous > >>> working behavior. > >>> I am opening a PMR next, but thought I would ask here also. Entire > >>> program follows > >>> > >>> /* This program works like the Unix tf -d command. It removes the > >>> */ > >>> /* special character (hex 4f) from records, thus leaving a clean, */ > >>> /* comma-delimited record in the output file. */ > >>> /* */ > >>> /* Modified 04/08/2004 by DMD; force abend if write error > >>> detected*/ > >>> /* Modified 08/23/2004 by DMD; remove carriage return & line feed.*/ > >>> /* */ > >>> #include <stdio.h> > >>> #include <string.h> > >>> #define MAXREC 5000 > >>> main (){ > >>> int rec_in_cnt; > >>> int rec_out_cnt; > >>> char rec_in[MAXREC]; > >>> char rec_out[MAXREC]; > >>> char delimitr[1]={0x00}; > >>> char comma [1]=","; > >>> char NL [1]={0x15}; /* new-line */ > >>> char CR [1]={0x0D}; /* carriage return */ > >>> char blnks[5000]; > >>> FILE * File_Out; > >>> FILE * File_In; > >>> int in_cnt, out_cnt; > >>> int incrmt, inc, blnk_cnt, recout_siz, FEOF; > >>> > >>> for (inc=0;inc<MAXREC;inc++) blnks[inc]=0x40; /* init blank array > >>> */ > >>> > >>> File_In = fopen("dd:stdin","rb,recfm=*,type=record"); > >>> if (!File_In){ > >>> printf("\n Could not open file STDIN. %d.\n",ferror); > >>> FEOF=1; } /* force exit */ > >>> > >>> File_Out = fopen("dd:stdout","wb,recfm=*,type=record"); > >>> if (!File_Out){ > >>> printf("\n Could not open file STDOUT. %d.\n,ferror"); > >>> FEOF=1; } /* force exit */ > >>> > >>> while ( (! feof(File_In)) && (!FEOF) ){ > >>> in_cnt = fread(rec_in,sizeof(char),MAXREC,File_In); > >>> for(inc=0;inc<in_cnt;inc++)rec_out[inc]=0x40; /* clean buff-out */ > >>> if (! feof(File_In)) { > >>> rec_in_cnt++; > >>> if ( !ferror(File_In) ){ > >>> for (incrmt=0,inc=0,blnk_cnt=0;incrmt<in_cnt;incrmt++) { > >>> if (strncmp(&rec_in[incrmt],delimitr,1)) /* if ! fill char */ > >>> if (strncmp(&rec_in[incrmt],blnks,1)){ /* if ! fill blnk */ > >>> if(!(strncmp(&rec_in[incrmt],comma,1))) /* if is comma */ > >>> blnk_cnt=0; /* drop prev blnks*/ > >>> else { > >>> memcpy(&rec_out[inc],&blnks[1],blnk_cnt); /* do blnk */ > >>> inc+=blnk_cnt; blnk_cnt=0; /* save & reset cnt */ > >>> } /* end of ELSE condition */ > >>> if ( (strncmp(&rec_in[incrmt],NL,1)) /* not newline */ > >>> && (strncmp(&rec_in[incrmt],CR,1)) ) /* not car-rtn */ > >>> memcpy(&rec_out[inc++],&rec_in[incrmt],1); /* do char */ > >>> else memcpy(&rec_out[inc++],&blnks[1],1); /* blank it */ > >>> } > >>> else blnk_cnt++; /* count the blank */ > >>> } /* end of FOR loop */ > >>> recout_siz = fwrite(rec_out,sizeof(char),in_cnt,File_Out); > >>> if (recout_siz < in_cnt) { /* if we didn't write whole record */ > >>> printf("Write error encountered."); /* for example B37. */ > >>> abort(); /* force abend. */ > >>> } > >>> rec_out_cnt++; > >>> } /* end of IF ferror condition */ > >>> else printf("\n Error reading input file.\n"); > >>> } /* end of IF feof condition */ > >>> } /* end of WHILE condition */ > >>> printf("Record counts for data compression utility > >>> GNDU2200.\n\n"); printf("Records read %d.\nRecords written > >>> %d.",rec_in_cnt,rec_out_cnt); fclose(File_In); fclose(File_Out); } > >>> /* end of MAIN */ > >>> > >>> Dave Gibney > >>> Information Technology Services > >>> Washington State University > >>> > >>> > >>> -------------------------------------------------------------------- > >>> -- For IBM-MAIN subscribe / signoff / archive access instructions, > >>> send email to [email protected] with the message: INFO > >>> IBM-MAIN > >>> > >> --------------------------------------------------------------------- > >> - For IBM-MAIN subscribe / signoff / archive access instructions, > >> send email to [email protected] with the message: INFO > >> IBM-MAIN > > ---------------------------------------------------------------------- > > For IBM-MAIN subscribe / signoff / archive access instructions, send > > email to [email protected] with the message: INFO IBM-MAIN > > ---------------------------------------------------------------------- > For IBM-MAIN subscribe / signoff / archive access instructions, send email to > [email protected] with the message: INFO IBM-MAIN ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to [email protected] with the message: INFO IBM-MAIN
