C compiler weirdness? (sample program)

Jit Keong Tan jit at SLIC.CELLBIO.DUKE.EDU
Sun Apr 14 11:51:15 AEST 1991


Let me join the crowd.


In article <1991Apr12.175909.5194 at helios.physics.utoronto.ca> mark at cita.toronto.edu writes:
>David Blythe wrote ...
>
> I recently dug up a copy of the hoc calculator described in kernighan & pike
> only to discover that the C compiler does not increment pc until after the
> function call returns in the following statment:
>                   (*(*pc++))();
> whereas the rest of the program is assuming it is done before the function is
> actually called.  Is the compiler interpretation supposed to be implementation
> dependent?  I would suspect not, but then I can't believe no one else has

CASE 1
======
My interpretation of (*(*pc++))() is

1) Parse the innermost parenthesis:
   i) location A =  *pc
   ii) pc++
2)  *(location A)  is a function pointer, call the function.

So pc should increment BEFORE the function is called.


CASE 2
======
If it is (**pc++)(), it should be fairly straight forward.

1) location A = *pc
2) *(location A) is a function pointer, call the function
3) pc++

So the increment should be AFTER the function is called.

===========================================

I wrote a little program to support my argument but of all 3 compilers
that I tested (SGI, GNU, SUN) did not fully support me.  So I may be
wrong.  But I still like to think that I have interpreted it correctly.

Here's my little program:
----------------------------------------------------------------------
/* JKT test of compiler behavior on function pointer */
/* Any comment is very much welcome.  jit at slic.cellbio.duke.edu */

#include <stdio.h>

void (**ptr)();
void (*fptr[3])();

void pr_all_ptr();
void fa();
void fb();
void fc();

main()
{
    fptr[0] = fa;
    fptr[1] = fb;
    fptr[2] = fc;

    ptr = fptr;
    printf("==============Before any changes\n");
    pr_all_ptr();

    printf("==============( **ptr++) ()\n");
    ptr = fptr;
    (**ptr++) ();
    printf("After ==( **ptr++) ()\n");
    pr_all_ptr();

    printf("==============( * (*ptr++)) ()\n");
    ptr = fptr;
    (* (*ptr++)) ();
    printf("After ==( * (*ptr++)) ()\n");
    pr_all_ptr();
}

void pr_all_ptr()
{
    printf("f?():  fa(%X h)  fb(%X h)  fc(%X h)\n",
	    (int)fa, (int)fb, (int)fc);
    printf("fptr: [0](%X h) [1](%X h) [2](%X h)\n",
	    (int)fptr[0], (int)fptr[1], (int)fptr[2]);
    printf("**ptr: %X h\n",(int)**ptr);
}

void fa()
{
    static int count=0;

    printf("fa being called %d\n",count++);
    pr_all_ptr();
    printf("Before Exiting fafafafafafa\n");
}

void fb()
{
    static int count=0;

    printf("fb being called %d\n",count);
    pr_all_ptr();
    printf("Before Exiting fbfbfbfbfbfbfb\n");
}

void fc()
{
    static int count=0;

    printf("fc being called %d\n",count);
    pr_all_ptr();
    printf("Before Exiting fcfcfcfcfcfcfc\n");
}

END OF PROGRAM 
----------------------------------------------------------------------

The following is the output of the sample program from SGI, GNU, SUN:

SGI
==============Before any changes
f?():  fa(40036C h)  fb(4003B4 h)  fc(4003F0 h)
fptr: [0](40036C h) [1](4003B4 h) [2](4003F0 h)
**ptr: 40036C h
==============( **ptr++) ()
fa being called 0
f?():  fa(40036C h)  fb(4003B4 h)  fc(4003F0 h)
fptr: [0](40036C h) [1](4003B4 h) [2](4003F0 h)
**ptr: 40036C h
Before Exiting fafafafafafa
After ==( **ptr++) ()
f?():  fa(40036C h)  fb(4003B4 h)  fc(4003F0 h)
fptr: [0](40036C h) [1](4003B4 h) [2](4003F0 h)
**ptr: 4003B4 h
==============( * (*ptr++)) ()
fa being called 1
f?():  fa(40036C h)  fb(4003B4 h)  fc(4003F0 h)
fptr: [0](40036C h) [1](4003B4 h) [2](4003F0 h)
**ptr: 40036C h
Before Exiting fafafafafafa
After ==( * (*ptr++)) ()
f?():  fa(40036C h)  fb(4003B4 h)  fc(4003F0 h)
fptr: [0](40036C h) [1](4003B4 h) [2](4003F0 h)
**ptr: 4003B4 h

GNU
==============Before any changes
f?():  fa(4003F0 h)  fb(400458 h)  fc(4004B0 h)
fptr: [0](4003F0 h) [1](400458 h) [2](4004B0 h)
**ptr: 4003F0 h
==============( **ptr++) ()
fa being called 0
f?():  fa(4003F0 h)  fb(400458 h)  fc(4004B0 h)
fptr: [0](4003F0 h) [1](400458 h) [2](4004B0 h)
**ptr: 400458 h
Before Exiting fafafafafafa
After ==( **ptr++) ()
f?():  fa(4003F0 h)  fb(400458 h)  fc(4004B0 h)
fptr: [0](4003F0 h) [1](400458 h) [2](4004B0 h)
**ptr: 400458 h
==============( * (*ptr++)) ()
fa being called 1
f?():  fa(4003F0 h)  fb(400458 h)  fc(4004B0 h)
fptr: [0](4003F0 h) [1](400458 h) [2](4004B0 h)
**ptr: 400458 h
Before Exiting fafafafafafa
After ==( * (*ptr++)) ()
f?():  fa(4003F0 h)  fb(400458 h)  fc(4004B0 h)
fptr: [0](4003F0 h) [1](400458 h) [2](4004B0 h)
**ptr: 400458 h

SUN
==============Before any changes
f?():  fa(2434 h)  fb(2488 h)  fc(24CC h)
fptr: [0](2434 h) [1](2488 h) [2](24CC h)
**ptr: 2434 h
==============( **ptr++) ()
fa being called 0
f?():  fa(2434 h)  fb(2488 h)  fc(24CC h)
fptr: [0](2434 h) [1](2488 h) [2](24CC h)
**ptr: 2488 h
Before Exiting fafafafafafa
After ==( **ptr++) ()
f?():  fa(2434 h)  fb(2488 h)  fc(24CC h)
fptr: [0](2434 h) [1](2488 h) [2](24CC h)
**ptr: 2488 h
==============( * (*ptr++)) ()
fa being called 1
f?():  fa(2434 h)  fb(2488 h)  fc(24CC h)
fptr: [0](2434 h) [1](2488 h) [2](24CC h)
**ptr: 2488 h
Before Exiting fafafafafafa
After ==( * (*ptr++)) ()
f?():  fa(2434 h)  fb(2488 h)  fc(24CC h)
fptr: [0](2434 h) [1](2488 h) [2](24CC h)
**ptr: 2488 h

--------------------------------------------------------
Jit Keong Tan     | internet: jit at slic.cellbio.duke.edu
(919) 684-8098    | bitnet  : tan00001 at dukemc.bitnet
--------------------------------------------------------
U.S. Mail:
Duke University Medical Center
Department Of Cell Biology
Box 3709
Nanaline Duke Bldg, Rm. 349
Durham, NC 27710



More information about the Comp.sys.sgi mailing list