public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Question for ISO C standards gurus
@ 2004-03-25 18:47 law
  2004-03-25 18:58 ` Dave Korn
  2004-03-25 18:59 ` Paul Jarc
  0 siblings, 2 replies; 9+ messages in thread
From: law @ 2004-03-25 18:47 UTC (permalink / raw)
  To: gcc


Given something like this:


execfuncdef(Estate state, int do_exec)
{
    Shfunc shf;
    char *s;
    int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0;
    Wordcode beg = state->pc, end;
    Eprog prog;
    Patprog *pp;
    LinkList names;
    end = beg + ((state->pc[-1]) >> 5);
    if (!(names = ecgetlist(state, *state->pc++, 2, &htok))) {
      state->pc = end;
      return 0;
    }
}


Does the ISO standard say anything about when the side effect of incrementing
state->pc takes effect?  Or is it implementation dependent?  Of particular
interest is whether or not the increment occurs before the call or after
the call.

jeff


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Question for ISO C standards gurus
  2004-03-25 18:47 Question for ISO C standards gurus law
@ 2004-03-25 18:58 ` Dave Korn
  2004-03-27  1:35   ` Diego Novillo
  2004-03-25 18:59 ` Paul Jarc
  1 sibling, 1 reply; 9+ messages in thread
From: Dave Korn @ 2004-03-25 18:58 UTC (permalink / raw)
  To: gcc


> -----Original Message-----
> From: gcc-owner On Behalf Of law@redhat.com
> Sent: 25 March 2004 18:03

> Given something like this:
> 
> 
> execfuncdef(Estate state, int do_exec)
> {
>     Shfunc shf;
>     char *s;
>     int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0;
>     Wordcode beg = state->pc, end;
>     Eprog prog;
>     Patprog *pp;
>     LinkList names;
>     end = beg + ((state->pc[-1]) >> 5);
>     if (!(names = ecgetlist(state, *state->pc++, 2, &htok))) {
>       state->pc = end;
>       return 0;
>     }
> }
> 
> 
> Does the ISO standard say anything about when the side effect 
> of incrementing
> state->pc takes effect?  Or is it implementation dependent?  Of 
> state->particular
> interest is whether or not the increment occurs before the 
> call or after the call.
> 
> jeff
 
  Isn't there a sequence point in between evaluating function args and
actually doing the function call that will force the side-effects to have
been applied?

http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=%22sequence+point%22+
function+call+evaluate+arguments

takes me to

http://www.langer.camelot.de/Articles/VSJ/SequencePoints/SequencePoints.html


which certainly suggests so:

"Here is the complete list of all sequence points in C++: 

at the end of a full expression 

after the evaluation of all function arguments in a function call and before
execution of any expressions in the function body 

after copying of a returned value and before execution of any expressions
outside the function 

after evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b 

after the initialization of each base and member in the constructor
initialization list "



    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....
 





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Question for ISO C standards gurus
  2004-03-25 18:47 Question for ISO C standards gurus law
  2004-03-25 18:58 ` Dave Korn
@ 2004-03-25 18:59 ` Paul Jarc
  2004-03-25 19:14   ` Dale Johannesen
  1 sibling, 1 reply; 9+ messages in thread
From: Paul Jarc @ 2004-03-25 18:59 UTC (permalink / raw)
  To: law; +Cc: gcc

law@redhat.com wrote:
>     if (!(names = ecgetlist(state, *state->pc++, 2, &htok))) {
...
> Of particular interest is whether or not the increment occurs before
> the call or after the call.

n869, 6.5.2.2p10:
# The order of evaluation of the function designator, the actual
# arguments, and subexpressions within the actual arguments is
# unspecified, but there is a sequence point before the actual call.

So the side effect would take place before the sequence point, and
thus before the call.  n869 was the latest public draft of C99; I
don't have a copy of the final standard.  It's possible that this
might have changed.


paul

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Question for ISO C standards gurus
  2004-03-25 18:59 ` Paul Jarc
@ 2004-03-25 19:14   ` Dale Johannesen
  0 siblings, 0 replies; 9+ messages in thread
From: Dale Johannesen @ 2004-03-25 19:14 UTC (permalink / raw)
  To: Paul Jarc; +Cc: gcc, Dale Johannesen, law


On Mar 25, 2004, at 10:12 AM, Paul Jarc wrote:

> law@redhat.com wrote:
>>     if (!(names = ecgetlist(state, *state->pc++, 2, &htok))) {
> ...
>> Of particular interest is whether or not the increment occurs before
>> the call or after the call.
>
> n869, 6.5.2.2p10:
> # The order of evaluation of the function designator, the actual
> # arguments, and subexpressions within the actual arguments is
> # unspecified, but there is a sequence point before the actual call.
>
> So the side effect would take place before the sequence point, and
> thus before the call.  n869 was the latest public draft of C99; I
> don't have a copy of the final standard.  It's possible that this
> might have changed.

The final standard says the same, as does C89.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Question for ISO C standards gurus
  2004-03-25 18:58 ` Dave Korn
@ 2004-03-27  1:35   ` Diego Novillo
  2004-03-27 11:25     ` Ian Lance Taylor
  2004-03-27 21:56     ` law
  0 siblings, 2 replies; 9+ messages in thread
From: Diego Novillo @ 2004-03-27  1:35 UTC (permalink / raw)
  To: gcc

On Thu, 2004-03-25 at 13:08, Dave Korn wrote:

> "Here is the complete list of all sequence points in C++: 
> 
> at the end of a full expression 
> 
> after the evaluation of all function arguments in a function call and before
> execution of any expressions in the function body 
> 
> after copying of a returned value and before execution of any expressions
> outside the function 
> 
> after evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b 
> 
> after the initialization of each base and member in the constructor
> initialization list "
> 
So, the program below should print 5?  It certainly doesn't with gcc 3.2
nor mainline:

int foo (int x)
{
  return x;
}

main ()
{
  int *p;
  int a[2];
  a[0] = 4;
  a[1] = 5;
  p = a;
  printf ("%d\n", foo (*p++));
}

It will print 5 if I use pre-increment on 'p', which is what I would've
expected (I'm no language lawyer, though).


Diego.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Question for ISO C standards gurus
  2004-03-27  1:35   ` Diego Novillo
@ 2004-03-27 11:25     ` Ian Lance Taylor
  2004-03-27 14:25       ` Diego Novillo
  2004-03-29 17:18       ` Dave Korn
  2004-03-27 21:56     ` law
  1 sibling, 2 replies; 9+ messages in thread
From: Ian Lance Taylor @ 2004-03-27 11:25 UTC (permalink / raw)
  To: Diego Novillo; +Cc: gcc

Diego Novillo <dnovillo@redhat.com> writes:

> On Thu, 2004-03-25 at 13:08, Dave Korn wrote:
> 
> > "Here is the complete list of all sequence points in C++: 
> > 
> > at the end of a full expression 
> > 
> > after the evaluation of all function arguments in a function call and before
> > execution of any expressions in the function body 
> > 
> > after copying of a returned value and before execution of any expressions
> > outside the function 
> > 
> > after evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b 
> > 
> > after the initialization of each base and member in the constructor
> > initialization list "
> > 
> So, the program below should print 5?  It certainly doesn't with gcc 3.2
> nor mainline:
> 
> int foo (int x)
> {
>   return x;
> }
> 
> main ()
> {
>   int *p;
>   int a[2];
>   a[0] = 4;
>   a[1] = 5;
>   p = a;
>   printf ("%d\n", foo (*p++));
> }
> 
> It will print 5 if I use pre-increment on 'p', which is what I would've
> expected (I'm no language lawyer, though).

I can't see any reason why that would print 5.  Based on the above, p
should be incremented before the function call to foo().  But that
doesn't change the value of *p++, which means "get the value at *p,
then increment p".  The above just means that this should not happen:
    t1 = *p;
    foo (t1);
    p = p + 1;
(at least, it should not be possible to observe that that happened; in
the above program, p, as a local variable whose address is not taken,
probably could be incremented after the function call, since there is
no way for anything to detect when the increment occurred.)

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Question for ISO C standards gurus
  2004-03-27 11:25     ` Ian Lance Taylor
@ 2004-03-27 14:25       ` Diego Novillo
  2004-03-29 17:18       ` Dave Korn
  1 sibling, 0 replies; 9+ messages in thread
From: Diego Novillo @ 2004-03-27 14:25 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

On Fri, 2004-03-26 at 20:25, Ian Lance Taylor wrote:

> I can't see any reason why that would print 5.  Based on the above, p
> should be incremented before the function call to foo().  But that
> doesn't change the value of *p++, which means "get the value at *p,
> then increment p".  The above just means that this should not happen:
>     t1 = *p;
>     foo (t1);
>     p = p + 1;
>
Thanks.  Now I know what the bug is, then.


Diego.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Question for ISO C standards gurus
  2004-03-27  1:35   ` Diego Novillo
  2004-03-27 11:25     ` Ian Lance Taylor
@ 2004-03-27 21:56     ` law
  1 sibling, 0 replies; 9+ messages in thread
From: law @ 2004-03-27 21:56 UTC (permalink / raw)
  To: Diego Novillo; +Cc: gcc

In message <1080348071.4600.244.camel@localhost.localdomain>, Diego Novillo wri
tes:
 >On Thu, 2004-03-25 at 13:08, Dave Korn wrote:
 >
 >> "Here is the complete list of all sequence points in C++: 
 >> 
 >> at the end of a full expression 
 >> 
 >> after the evaluation of all function arguments in a function call and befor
 >e
 >> execution of any expressions in the function body 
 >> 
 >> after copying of a returned value and before execution of any expressions
 >> outside the function 
 >> 
 >> after evaluation of the first expression in a&&b,  a||b,  a?b:c,  or  a,b 
 >> 
 >> after the initialization of each base and member in the constructor
 >> initialization list "
 >> 
 >So, the program below should print 5?  It certainly doesn't with gcc 3.2
 >nor mainline:
No, it should print 4.

First you evaluate the argument to produce the passed-in value, note this
will not reflect any post side effects.  Then you emit the post side effects.

This effectively means that when you have post side effects that you have
to compute the value for the argument into a temporary and use the temporary
in the function call.

The ordering of stuff for a call effectively looks like

prequeue fncall
prequeue arg0
prequeue arg1
prequeue arg2
...
prequeue argn

temp0 = arg0
temp1 = arg1
temp2 = arg2
...
tempn = argn

postqueue arg0
postqueue arg1
postqueue arg2
...
postqueue argn

fncall (temp0, temp1, temp2, ... tempn)

poster fncall

Clearly for cases where there are no postqueues for a particular argument
you need not create a temporary and instead can use the evaluated argument
directly in the call.

Jeff


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: Question for ISO C standards gurus
  2004-03-27 11:25     ` Ian Lance Taylor
  2004-03-27 14:25       ` Diego Novillo
@ 2004-03-29 17:18       ` Dave Korn
  1 sibling, 0 replies; 9+ messages in thread
From: Dave Korn @ 2004-03-29 17:18 UTC (permalink / raw)
  To: gcc


> -----Original Message-----
> From: gcc-owner Behalf Of Ian Lance Taylor
> Sent: 27 March 2004 01:26

> Diego Novillo writes:
> 
> > On Thu, 2004-03-25 at 13:08, Dave Korn wrote:
> > 
> > > "Here is the complete list of all sequence points in C++: 
[...snip...]
> > > after the evaluation of all function arguments in a function call 
> > > and before execution of any expressions in the function body

[...snip...]
> > So, the program below should print 5?  It certainly doesn't 
> with gcc 
> > 3.2 nor mainline:
> > 
> > int foo (int x)
> > {
> >   return x;
> > }
> > 
> > main ()
> > {
> >   int *p;
> >   int a[2];
> >   a[0] = 4;
> >   a[1] = 5;
> >   p = a;
> >   printf ("%d\n", foo (*p++));
> > }
> > 
> > It will print 5 if I use pre-increment on 'p', which is what I 
> > would've expected (I'm no language lawyer, though).
> 
> I can't see any reason why that would print 5.  Based on the 
> above, p should be incremented before the function call to 
> foo().  But that doesn't change the value of *p++, which 
> means "get the value at *p, then increment p".  The above 
> just means that this should not happen:
>     t1 = *p;
>     foo (t1);
>     p = p + 1;
> (at least, it should not be possible to observe that that 
> happened; in the above program, p, as a local variable whose 
> address is not taken, probably could be incremented after the 
> function call, since there is no way for anything to detect 
> when the increment occurred.)
> 
> Ian



Indeed, that's my understanding as well.  I'd also mention that if foo was a
nested function and had access from its inner scope to the value of *p in
the enclosing function, it should be 5 at the time control flow was in foo.



    cheers, 
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-03-29 10:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-25 18:47 Question for ISO C standards gurus law
2004-03-25 18:58 ` Dave Korn
2004-03-27  1:35   ` Diego Novillo
2004-03-27 11:25     ` Ian Lance Taylor
2004-03-27 14:25       ` Diego Novillo
2004-03-29 17:18       ` Dave Korn
2004-03-27 21:56     ` law
2004-03-25 18:59 ` Paul Jarc
2004-03-25 19:14   ` Dale Johannesen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).