Hmm, I'm not getting the same result! When I compile with ARCH(5) there
is only one strlen() call (SRST) and the value is retained in a register.
BTW, I removed #undef strlen. What is the purpose of that directive?
* int i;
* for(i=0;i<argc;i++) {
LTR r1,r1
LA r3,0
JNH @1L6
LA r5,0
LR r8,r1
@1L3 DS 0H
* if ('\r' == *(argv i +strlen(argv i )) )
L r9,(*)uchar*(r5,r2,0)
LR r11,r9
NILH r11,H'32767'
LA r0,0
LR r10,r11
SRST r0,r10
JO *-4
LR r10,r0
SLR r10,r11
LLGC r0,(*)uchar(r10,r9,0)
CHI r0,H'13'
JNE @1L5
* *(argv i +strlen(argv i ))='\0';
AL r10,(*)uchar*(r5,r2,0)
MVI (*)uchar(r10,0),0
@1L5 DS 0H
LA r5,#AMNESIA(,r5,4)
BRCT r8,@1L3
* }
* return 0;
* }
If I compile using ARCH(9) for our z114 the code is even more succinct.
I can't pick a hole in it.
* int i;
* for(i=0;i<argc;i++) {
LA r3,0
LTR r1,r1
JNH @1L6
LA r5,0
RISBHG r0,r1,H'0',H'159',H'32'
@1L3 DS 0H
* if ('\r' == *(argv i +strlen(argv i )) )
L r10,(*)uchar*(r5,r2,0)
LA r0,0
LR r8,r10
NILH r8,H'32767'
LR r9,r8
SRST r0,r9
JO *-4
SLRK r8,r0,r8
LLC r0,(*)uchar(r8,r10,0)
CHI r0,H'13'
JNE @1L5
* *(argv i +strlen(argv i ))='\0';
AL r8,(*)uchar*(r5,r2,0)
MVI (*)uchar(r8,0),0
@1L5 DS 0H
LA r5,#AMNESIA(,r5,4)
BRCTH r0,@1L3
* }
* return 0;
On 23/02/2014 1:16 PM, John McKown wrote:
Just for fun, I wrote a very small C program. I compiled it on Linux/Intel
using GCC 4.8.2. I then got it compiled on z/OS 1.13. The program is very
small:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#undef strlen
int main (int argc, char *argv[]) {
int i;
for(i=0;i<argc;i++) {
if ('\r' == *(argv[i]+strlen(argv[i])) )
*(argv[i]+strlen(argv[i]))='\0';
}
return 0;
}
On the z/OS compiler, under UNIX, using the -O5 switch to optimize, the
compiler generated in-line code for both calls to strlen, despite the fact
that they had the identical arguments with no possibility of modification.
The GCC compiler, on the other hand, retained the result of the first
strlen() and used that value in the second statement. Actually, GCC
retained the value of "argv[i]+strlen(argv[i])", so that it the equivalent
of a CLI, JNE, MVI to change the \r to \0.
Of course, I can help the compiler by changing my code slightly:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#undef strlen
int main (int argc, char *argv[]) {
int i;
char *lastchar; */
for(i=0;i<argc;i++) {
lastchar=argv[i]+strlen(argv[i]);
if ('\r' == *lastchar)
*lastchar='\0';
}
return 0;
}
Much nicer. But, again curiously, instead of doing a CLI and MVI, the
compiler using -O5 did:
SLR R0,R0
IC R1,0(,R1)
CHI R1,=H'13'
BNE ...
On ARCH(7), it was a bit better, replacing the SLR/IC pair with an LLC
instruction.
I failed the compiler class in college, so for all I know there is a
perfectly good reason why the z/OS compiler does it this way. But I just
found it curious and thought that I'd throw it out onto the forum.
Hopefully someone can explain it to me. BTW, I compile the above using no
optimization, -O2, -O3, -O3, and -O5. I got the identical assembler in all
cases. This was true in the default ARCH(5) and ARCH(7).
I know some with likely say that I'm grasping at straws. Perhaps so. But if
the compiler misses such a simple optimization, what else might it miss?
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN