public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* statement expressions and extended asm bug?
@ 2004-03-15 11:26 Gunther Nikl
  2004-03-15 11:46 ` Nathan Sidwell
                   ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Gunther Nikl @ 2004-03-15 11:26 UTC (permalink / raw)
  To: gcc

Hello!

The following sample testcase using statement expressions and extended
asm is treated differently with GCC 2.95.2 and GCC 3.3:

-- cut --
void foo(int,int);

#define f1() \
({ register int _d0 __asm("d0"); \
   __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc", "memory"); \
   _d0; })

#define f2() \
({ register int _d0 __asm("d0"); \
   __asm volatile ("moveq #12,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc", "memory"); \
   _d0;})

void bar(void) {
  foo(f1(),f2());
}
-- cut --

GCC 2.95.2 generated with -O this:

_bar:	moveq #12,d0
	movel d0,sp@-
	moveq #11,d0
	movel d0,sp@-
	jbsr _foo
	addql #8,sp

but 3.3 this:

_bar:	moveq #12,d0
	moveq #11,d0
	movel d0,sp@-
	movel d0,sp@-
	jbsr _foo
	addql #8,sp

GCC 3.3 moves the statement expressions for f1/f2 out of the function call.
This clobbers the return value of the statement expression. Is that because
f1/f2 are wrong or because of a GCC bug?

Thank you,
Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 11:26 statement expressions and extended asm bug? Gunther Nikl
@ 2004-03-15 11:46 ` Nathan Sidwell
  2004-03-15 13:50   ` Gunther Nikl
  2004-03-16 23:10 ` Kai Henningsen
  2004-03-16 23:10 ` Kai Henningsen
  2 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-15 11:46 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc

Gunther Nikl wrote:
> Hello!
> 
> The following sample testcase using statement expressions and extended
> asm is treated differently with GCC 2.95.2 and GCC 3.3:
> 
> -- cut --
> void foo(int,int);
> 
> #define f1() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc", "memory"); \
>    _d0; })
> 
> #define f2() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #12,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc", "memory"); \
>    _d0;})
> 
> void bar(void) {
>   foo(f1(),f2());
> }
> -- cut --
> 
> GCC 2.95.2 generated with -O this:
> 
> _bar:	moveq #12,d0
> 	movel d0,sp@-
> 	moveq #11,d0
> 	movel d0,sp@-
> 	jbsr _foo
> 	addql #8,sp
> 
> but 3.3 this:
> 
> _bar:	moveq #12,d0
> 	moveq #11,d0
> 	movel d0,sp@-
> 	movel d0,sp@-
> 	jbsr _foo
> 	addql #8,sp
> 
> GCC 3.3 moves the statement expressions for f1/f2 out of the function call.
> This clobbers the return value of the statement expression. Is that because
> f1/f2 are wrong or because of a GCC bug?
Your code is ill formed.  Ignoring the asm and statement expression syntax for
the moment, it is equivalent to,
   int v;
   foo ((v = 11, v), (v = 12, v));
this violates the sequence point constraints of C.

I suspect if you did not allocate variable _d0 to an explicit register, then
things would behave.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 11:46 ` Nathan Sidwell
@ 2004-03-15 13:50   ` Gunther Nikl
  2004-03-15 14:03     ` Nathan Sidwell
  0 siblings, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-15 13:50 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Gunther Nikl, gcc

On Mon, Mar 15, 2004 at 11:46:30AM +0000, Nathan Sidwell wrote:
> Gunther Nikl wrote:
> >Hello!
> >
> >The following sample testcase using statement expressions and extended
> >asm is treated differently with GCC 2.95.2 and GCC 3.3:
> >
> >-- cut --
> >void foo(int,int);
> >
> >#define f1() \
> >({ register int _d0 __asm("d0"); \
> >   __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", 
> >   "cc", "memory"); \
> >   _d0; })
> >
> >#define f2() \
> >({ register int _d0 __asm("d0"); \
> >   __asm volatile ("moveq #12,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", 
> >   "cc", "memory"); \
> >   _d0;})
> >
> >void bar(void) {
> >  foo(f1(),f2());
> >}
> >-- cut --
> >
> >GCC 2.95.2 generated with -O this:
> >
> >_bar:	moveq #12,d0
> >	movel d0,sp@-
> >	moveq #11,d0
> >	movel d0,sp@-
> >	jbsr _foo
> >	addql #8,sp
> >
> >but 3.3 this:
> >
> >_bar:	moveq #12,d0
> >	moveq #11,d0
> >	movel d0,sp@-
> >	movel d0,sp@-
> >	jbsr _foo
> >	addql #8,sp
> >
> >GCC 3.3 moves the statement expressions for f1/f2 out of the function call.
> >This clobbers the return value of the statement expression. Is that because
> >f1/f2 are wrong or because of a GCC bug?
> Your code is ill formed.  Ignoring the asm and statement expression syntax 
> for the moment, it is equivalent to,
>   int v;
>   foo ((v = 11, v), (v = 12, v));
> this violates the sequence point constraints of C.

  That would explain the behaviour. Are you sure that your interpretation
  is right? The documenation says:

    "...allows you to use loops, switches, and local variables within an
     expression."

  This seems to imply your rewrite is wrong.

> I suspect if you did not allocate variable _d0 to an explicit register,
> then things would behave.

  Thats correct. If I assign the register variable to a non-register
  variable inside the expression, the generated code works as expected.
  However, if I understand you correctly that might be an accident
  nonetheless. Consider the maxint example from the documentation about
  statement expression. Using it twice in a function call should then
  also violate the sequence point constraints of C, shouldn't it?

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 13:50   ` Gunther Nikl
@ 2004-03-15 14:03     ` Nathan Sidwell
  2004-03-15 14:49       ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-15 14:03 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc

Gunther Nikl wrote:
>   That would explain the behaviour. Are you sure that your interpretation
>   is right? The documenation says:
> 
>     "...allows you to use loops, switches, and local variables within an
>      expression."
correct
>>I suspect if you did not allocate variable _d0 to an explicit register,
>>then things would behave.
> 
> 
>   Thats correct. If I assign the register variable to a non-register
>   variable inside the expression, the generated code works as expected.
>   However, if I understand you correctly that might be an accident
>   nonetheless. Consider the maxint example from the documentation about
No, that's not an accident.
>   statement expression. Using it twice in a function call should then
>   also violate the sequence point constraints of C, shouldn't it?
no.

It is your explicit allocation of the two temporary variables into the
same register that is breaking things.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 14:03     ` Nathan Sidwell
@ 2004-03-15 14:49       ` Gunther Nikl
  2004-03-15 15:20         ` Nathan Sidwell
  0 siblings, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-15 14:49 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc

On Mon, Mar 15, 2004 at 02:03:10PM +0000, Nathan Sidwell wrote:
> It is your explicit allocation of the two temporary variables into the
> same register that is breaking things.

  Ok, thats what I wanted to know. So, if I assign the temporary explict
  register variable containing the result to a non-register variable, then
  the expressions become well-formed and don't violate other constraints,
  right?

  Thank you for your help.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 14:49       ` Gunther Nikl
@ 2004-03-15 15:20         ` Nathan Sidwell
  2004-03-15 15:35           ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-15 15:20 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc

Gunther Nikl wrote:
> On Mon, Mar 15, 2004 at 02:03:10PM +0000, Nathan Sidwell wrote:
> 
>>It is your explicit allocation of the two temporary variables into the
>>same register that is breaking things.
> 
> 
>   Ok, thats what I wanted to know. So, if I assign the temporary explict
>   register variable containing the result to a non-register variable, then
>   the expressions become well-formed and don't violate other constraints,
>   right?
If you are asking whether
   ({int i; int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); i = j; i;})
will DTRT, the answer is no.

If you are asking something else, you'll have to rephrase it.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 15:20         ` Nathan Sidwell
@ 2004-03-15 15:35           ` Gunther Nikl
  2004-03-15 15:54             ` Nathan Sidwell
  0 siblings, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-15 15:35 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc

On Mon, Mar 15, 2004 at 03:20:08PM +0000, Nathan Sidwell wrote:
> Gunther Nikl wrote:
> >On Mon, Mar 15, 2004 at 02:03:10PM +0000, Nathan Sidwell wrote:
> >
> >>It is your explicit allocation of the two temporary variables into the
> >>same register that is breaking things.
> >
> >  Ok, thats what I wanted to know. So, if I assign the temporary explict
> >  register variable containing the result to a non-register variable, then
> >  the expressions become well-formed and don't violate other constraints,
> >  right?
> If you are asking whether
>   ({int i; int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); i = j; i;})
> will DTRT, the answer is no.

  I was considering writing it like this:

    ({ int i = \
       ({int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); j;}); \
       i; \
    })

  This seems to work with 3.3+.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 15:35           ` Gunther Nikl
@ 2004-03-15 15:54             ` Nathan Sidwell
  2004-03-15 16:41               ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-15 15:54 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc

Gunther Nikl wrote:
> On Mon, Mar 15, 2004 at 03:20:08PM +0000, Nathan Sidwell wrote:

>>If you are asking whether
>>  ({int i; int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); i = j; i;})
>>will DTRT, the answer is no.
> 
> 
>   I was considering writing it like this:
> 
>     ({ int i = \
>        ({int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); j;}); \
>        i; \
>     })
> 
>   This seems to work with 3.3+.
that is equivalent to my example, the code still looks like it is undefined.

Why must you assign j to register d0?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 15:54             ` Nathan Sidwell
@ 2004-03-15 16:41               ` Gunther Nikl
  2004-03-15 17:50                 ` Nathan Sidwell
  0 siblings, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-15 16:41 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc

On Mon, Mar 15, 2004 at 03:54:43PM +0000, Nathan Sidwell wrote:
> Gunther Nikl wrote:
> >On Mon, Mar 15, 2004 at 03:20:08PM +0000, Nathan Sidwell wrote:
> 
> >>If you are asking whether
> >> ({int i; int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); i = j; 
> >> i;})
> >>will DTRT, the answer is no.
> >
> >  I was considering writing it like this:
> >
> >    ({ int i = \
> >       ({int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); j;}); \
> >       i; \
> >    })
> >
> >  This seems to work with 3.3+.
>
> that is equivalent to my example, the code still looks like it is undefined.

  Argh! :-( In that case it "works" now by chanceonly, right?

> Why must you assign j to register d0?

  I tried to give a simplified asm() example. The real asm code has a call
  instruction and the called function expects their arguments in certain
  registers and returns its result in "d0". To avoid the use of a stub
  function, a statement expression+extended asm is used.

  Sometime ago I thought about using a dummy asm instruction that gets all
  inputs and then making the call with a C expression. However, I don't
  think thats safe. Maybe GCC then thinks the asm instruction is dead
  and deletes it together with its inputs or inserts code between the
  asm instruction and the call clobbering inputs. Currently this seems
  to work.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 16:41               ` Gunther Nikl
@ 2004-03-15 17:50                 ` Nathan Sidwell
  2004-03-15 20:25                   ` Jamie Lokier
  0 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-15 17:50 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc

Gunther Nikl wrote:
> On Mon, Mar 15, 2004 at 03:54:43PM +0000, Nathan Sidwell wrote:
> 
>>Gunther Nikl wrote:
>>
>>>On Mon, Mar 15, 2004 at 03:20:08PM +0000, Nathan Sidwell wrote:
>>
>>>>If you are asking whether
>>>>({int i; int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); i = j; 
>>>>i;})
>>>>will DTRT, the answer is no.
>>>
>>> I was considering writing it like this:
>>>
>>>   ({ int i = \
>>>      ({int j __asm__("d0"); volatile asm ("..." : "=r"(j)...); j;}); \
>>>      i; \
>>>   })
>>>
>>> This seems to work with 3.3+.
>>
>>that is equivalent to my example, the code still looks like it is undefined.
> 
> 
>   Argh! :-( In that case it "works" now by chanceonly, right?
see below

>>Why must you assign j to register d0?
> 
> 
>   I tried to give a simplified asm() example. The real asm code has a call
>   instruction and the called function expects their arguments in certain
>   registers and returns its result in "d0". To avoid the use of a stub
>   function, a statement expression+extended asm is used.
Ideally you want a register class that only contains d0, but I suspect
there isn't one. Perhaps the following will do what you want,

inline int foo (int arg_)
{
   int result __asm("d0");
   int arg __asm("d1"); // for sake of argument

   arg = arg_;
   asm ("call whereever": "=r(result)" :"r(arg)" : ...);

   return result;
}

This is subtly different from the statement expression form, because
the result of a C statement expression can be an lvalue, whereas here
it is an rvalue. (in g++, statement expressions always produce a result
'as-if' by 'return').

Perhaps your rewriting of the asm is effectively making the
same change.  Your example is IMHO another case of why
statement-exprs should return rvalues!

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 17:50                 ` Nathan Sidwell
@ 2004-03-15 20:25                   ` Jamie Lokier
  2004-03-15 20:39                     ` Joseph S. Myers
                                       ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Jamie Lokier @ 2004-03-15 20:25 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Gunther Nikl, gcc

Nathan Sidwell wrote:
> inline int foo (int arg_)
> {
>   int result __asm("d0");
>   int arg __asm("d1"); // for sake of argument
> 
>   arg = arg_;
>   asm ("call whereever": "=r(result)" :"r(arg)" : ...);
> 
>   return result;
> }
> 
> This is subtly different from the statement expression form, because
> the result of a C statement expression can be an lvalue, whereas here
> it is an rvalue. (in g++, statement expressions always produce a result
> 'as-if' by 'return').

More to the point, calling the foo(arg) above from different function
arguments isn't a sequence-point violation, unlike calling the
statement-expressions.

    function(foo(arg1), foo(arg2));

could evaluate the two calls to foo() in either order, but it must
finish one completely before the other.

Perhaps this is a flaw in GCC's implementation of
statement-expression, because s-e is intended for use in macros
function-like macros -- whose callers don't know they are calling a
macro.

-- Jamie

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

* Re: statement expressions and extended asm bug?
  2004-03-15 20:25                   ` Jamie Lokier
@ 2004-03-15 20:39                     ` Joseph S. Myers
  2004-03-15 20:41                     ` Gabriel Dos Reis
  2004-03-16  9:12                     ` Nathan Sidwell
  2 siblings, 0 replies; 38+ messages in thread
From: Joseph S. Myers @ 2004-03-15 20:39 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Nathan Sidwell, Gunther Nikl, gcc

On Mon, 15 Mar 2004, Jamie Lokier wrote:

>     function(foo(arg1), foo(arg2));
> 
> could evaluate the two calls to foo() in either order, but it must
> finish one completely before the other.
> 
> Perhaps this is a flaw in GCC's implementation of
> statement-expression, because s-e is intended for use in macros
> function-like macros -- whose callers don't know they are calling a
> macro.

We've never established the sequence point rules for statement
expressions, but I previously noted
<http://gcc.gnu.org/ml/gcc/2003-07/msg01461.html> the case for having them
follow the non-overlapping rule for function calls, especially given that
inline functions get internally expanded into statement expressions.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

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

* Re: statement expressions and extended asm bug?
  2004-03-15 20:25                   ` Jamie Lokier
  2004-03-15 20:39                     ` Joseph S. Myers
@ 2004-03-15 20:41                     ` Gabriel Dos Reis
  2004-03-15 20:52                       ` Jamie Lokier
  2004-03-16  9:12                     ` Nathan Sidwell
  2 siblings, 1 reply; 38+ messages in thread
From: Gabriel Dos Reis @ 2004-03-15 20:41 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Nathan Sidwell, Gunther Nikl, gcc

Jamie Lokier <jamie@shareable.org> writes:

| Perhaps this is a flaw in GCC's implementation of
| statement-expression, because s-e is intended for use in macros
| function-like macros -- whose callers don't know they are calling a
| macro.

Well, that is called inline functions :-)
If you consistently and predictably inline functions, people won't
ddamage their codes and run into troubles -- even if "they asked for
it". 

-- Gaby

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

* Re: statement expressions and extended asm bug?
  2004-03-15 20:41                     ` Gabriel Dos Reis
@ 2004-03-15 20:52                       ` Jamie Lokier
  2004-03-16 14:54                         ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Jamie Lokier @ 2004-03-15 20:52 UTC (permalink / raw)
  To: Gabriel Dos Reis; +Cc: Nathan Sidwell, Gunther Nikl, gcc

Gabriel Dos Reis wrote:
> | Perhaps this is a flaw in GCC's implementation of
> | statement-expression, because s-e is intended for use in macros
> | function-like macros -- whose callers don't know they are calling a
> | macro.
> 
> Well, that is called inline functions :-)

Yes, but as the primary reason for statement expressions is to make
macros that can be called like functions, and there are vast numbers
of macros written using that assumption, perhaps the preferred semantic
is that they behave like it :)

> If you consistently and predictably inline functions, people won't
> ddamage their codes and run into troubles -- even if "they asked for it". 

Yes.
That is preferable now that the inliner is better than it used to be.

There are still cases where inline isn't a feasible replacement, such
as function-like macros in C which can work with more than one type of
argument.  The GCC manual has precisely such an example.

-- Jamie

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

* Re: statement expressions and extended asm bug?
  2004-03-15 20:25                   ` Jamie Lokier
  2004-03-15 20:39                     ` Joseph S. Myers
  2004-03-15 20:41                     ` Gabriel Dos Reis
@ 2004-03-16  9:12                     ` Nathan Sidwell
  2004-03-16 13:05                       ` Joseph S. Myers
  2004-03-16 14:18                       ` Gunther Nikl
  2 siblings, 2 replies; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-16  9:12 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Gunther Nikl, gcc

Jamie Lokier wrote:

> More to the point, calling the foo(arg) above from different function
> arguments isn't a sequence-point violation, unlike calling the
> statement-expressions.
> 
>     function(foo(arg1), foo(arg2));
> 
> could evaluate the two calls to foo() in either order, but it must
> finish one completely before the other.
I thought that was true in C++ but not C. Perhaps C99 tightened it
up, or my memory is bad, or C89 never actually specified, given
that it didn't have 'inline', so overlapping was not feasible.

Gunther's code became invalid becuase the two statement expressions
both returned different lvalues, but forced into the same register (via
yet another GNU extension).

It is probably an 'accident of design' that tree inlining into statement
exprs DTRT, because functions do not return lvalues at that level, and
the expander is sequential in its RTL emission.

Having statement expressions silently extend the lifetime of an lvalue
declared within is a great way to trip users up.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-16  9:12                     ` Nathan Sidwell
@ 2004-03-16 13:05                       ` Joseph S. Myers
  2004-03-16 14:18                       ` Gunther Nikl
  1 sibling, 0 replies; 38+ messages in thread
From: Joseph S. Myers @ 2004-03-16 13:05 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Jamie Lokier, Gunther Nikl, gcc

On Tue, 16 Mar 2004, Nathan Sidwell wrote:

> Jamie Lokier wrote:
> 
> > More to the point, calling the foo(arg) above from different function
> > arguments isn't a sequence-point violation, unlike calling the
> > statement-expressions.
> > 
> >     function(foo(arg1), foo(arg2));
> > 
> > could evaluate the two calls to foo() in either order, but it must
> > finish one completely before the other.
> I thought that was true in C++ but not C. Perhaps C99 tightened it
> up, or my memory is bad, or C89 never actually specified, given
> that it didn't have 'inline', so overlapping was not feasible.

That function calls do not overlap is stated in the response to DR#087.  
I.e., you're meant to deduce this from the text of the standard.  This is
supposed to be one of the responses that also applies to C99.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

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

* Re: statement expressions and extended asm bug?
  2004-03-16  9:12                     ` Nathan Sidwell
  2004-03-16 13:05                       ` Joseph S. Myers
@ 2004-03-16 14:18                       ` Gunther Nikl
  2004-03-16 17:54                         ` Nathan Sidwell
  1 sibling, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-16 14:18 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc, Jamie Lokier

On Mon, Mar 15, 2004 at 05:50:36PM +0000, Nathan Sidwell wrote:
> Gunther Nikl wrote:
> >  I tried to give a simplified asm() example. The real asm code has a call
> >  instruction and the called function expects their arguments in certain
> >  registers and returns its result in "d0". To avoid the use of a stub
> >  function, a statement expression+extended asm is used.
> Ideally you want a register class that only contains d0, but I suspect
> there isn't one. Perhaps the following will do what you want,
> 
> inline int foo (int arg_)
> {
>   int result __asm("d0");
>   int arg __asm("d1"); // for sake of argument
> 
>   arg = arg_;
>   asm ("call whereever": "=r(result)" :"r(arg)" : ...);
> 
>   return result;
> }
> 
> This is subtly different from the statement expression form, because
> the result of a C statement expression can be an lvalue, whereas here
> it is an rvalue.

  Initially, inline functions similiar to the above were used. Later there
  was the switch to s-e because parsing many inline functions was slow
  and the parsed functions occupy memory. In contrast when using s-e, the
  "functions" are constructed on demand. This used to be faster and less
  memory hungry than inline functions. Another advantage was that one
  required implict parameter which had to be global before, could now be
  a function local, structure element or function parameter. If possible
  I would like to keep the s-e usage.

> (in g++, statement expressions always produce a result 'as-if' by
> 'return').

  Does that mean with g++ it should work? I just tried with 3.3 and it
  doesn't.

> Perhaps your rewriting of the asm is effectively making the same change.

  AFAICT from the discussion so far, even if it works with the nested
  s-e's, its still wrong.

> Your example is IMHO another case of why statement-exprs should return
> rvalues!

  And then I could use s-e as a function argument as I did?

On Tue, Mar 16, 2004 at 09:12:15AM +0000, Nathan Sidwell wrote:
> Having statement expressions silently extend the lifetime of an lvalue
> declared within is a great way to trip users up.

  Is that "my" problem?

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-15 20:52                       ` Jamie Lokier
@ 2004-03-16 14:54                         ` Gunther Nikl
  0 siblings, 0 replies; 38+ messages in thread
From: Gunther Nikl @ 2004-03-16 14:54 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Gabriel Dos Reis, Nathan Sidwell, gcc

On Mon, Mar 15, 2004 at 08:51:58PM +0000, Jamie Lokier wrote:
> Gabriel Dos Reis wrote:
> > | Perhaps this is a flaw in GCC's implementation of
> > | statement-expression, because s-e is intended for use in macros
> > | function-like macros -- whose callers don't know they are calling a
> > | macro.

  That was the motivation: function-like macros.

> > Well, that is called inline functions :-)
> 
> Yes, but as the primary reason for statement expressions is to make
> macros that can be called like functions, and there are vast numbers
> of macros written using that assumption, perhaps the preferred semantic
> is that they behave like it :)

  Does that mean the current 3.3+ behaviour regarding s-e is a bug?
  If thats the case, shall I file a pr?

> > If you consistently and predictably inline functions, people won't
> > ddamage their codes and run into troubles -- even if "they asked for it". 
> 
> Yes.
> That is preferable now that the inliner is better than it used to be.

  How well does that work in contrast to s-e? In my case the preprocessor
  did most of the work, that is the compiler saw only the really used
  "functions". With inlining the compiler has to parse all inline
  functions even if most of them won't be used at all.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-16 14:18                       ` Gunther Nikl
@ 2004-03-16 17:54                         ` Nathan Sidwell
  2004-03-17 13:13                           ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-16 17:54 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: gcc, Jamie Lokier

Gunther Nikl wrote:
> On Mon, Mar 15, 2004 at 05:50:36PM +0000, Nathan Sidwell wrote:

>>(in g++, statement expressions always produce a result 'as-if' by
>>'return').
> 
> 
>   Does that mean with g++ it should work? I just tried with 3.3 and it
>   doesn't.
It seems that those changes didn't make it to 3.3, but will be in 3.4.
See PR 11295 for details

>>Perhaps your rewriting of the asm is effectively making the same change.
>   AFAICT from the discussion so far, even if it works with the nested
>   s-e's, its still wrong.
I think the nested s-e's are ok.


>>Your example is IMHO another case of why statement-exprs should return
>>rvalues!
>   And then I could use s-e as a function argument as I did?
only the nested ones,

> On Tue, Mar 16, 2004 at 09:12:15AM +0000, Nathan Sidwell wrote:
> 
>>Having statement expressions silently extend the lifetime of an lvalue
>>declared within is a great way to trip users up.
>   Is that "my" problem?
er, sort of. IMHO it is a bug in the mechanism by which s-e's return
values, and you have fallen over it by your use of the register asm
variable.

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-15 11:26 statement expressions and extended asm bug? Gunther Nikl
  2004-03-15 11:46 ` Nathan Sidwell
  2004-03-16 23:10 ` Kai Henningsen
@ 2004-03-16 23:10 ` Kai Henningsen
  2004-03-17 10:46   ` Gunther Nikl
  2004-03-17 15:36   ` Hans-Peter Nilsson
  2 siblings, 2 replies; 38+ messages in thread
From: Kai Henningsen @ 2004-03-16 23:10 UTC (permalink / raw)
  To: gcc

gni@gecko.de (Gunther Nikl)  wrote on 15.03.04 in <20040315112744.GA86063@lorien.int.gecko.de>:

> #define f1() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> "memory"); \    _d0; })

If the problem is the possibility of returning lvalues from statement  
expressions, what would happen with the following?

#define f1() \
({ register int _d0 __asm("d0"); \
   __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
"memory"); \    _d0 + 0; })

(The only change is at the end.)

MfG Kai

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

* Re: statement expressions and extended asm bug?
  2004-03-15 11:26 statement expressions and extended asm bug? Gunther Nikl
  2004-03-15 11:46 ` Nathan Sidwell
@ 2004-03-16 23:10 ` Kai Henningsen
  2004-03-16 23:10 ` Kai Henningsen
  2 siblings, 0 replies; 38+ messages in thread
From: Kai Henningsen @ 2004-03-16 23:10 UTC (permalink / raw)
  To: gcc

gni@gecko.de (Gunther Nikl)  wrote on 15.03.04 in <20040315112744.GA86063@lorien.int.gecko.de>:

> #define f1() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> "memory"); \    _d0; })

If the problem is the possibility of returning lvalues from statement  
expressions, what would happen with the following?

#define f1() \
({ register int _d0 __asm("d0"); \
   __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
"memory"); \    _d0 + 0; })

(The only change is at the end.)

Shouldn't this force a rvalue return?

MfG Kai

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

* Re: statement expressions and extended asm bug?
  2004-03-16 23:10 ` Kai Henningsen
@ 2004-03-17 10:46   ` Gunther Nikl
  2004-03-19 22:38     ` Kai Henningsen
  2004-03-17 15:36   ` Hans-Peter Nilsson
  1 sibling, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-17 10:46 UTC (permalink / raw)
  To: Kai Henningsen; +Cc: gcc

On Tue, Mar 16, 2004 at 09:56:00PM +0200, Kai Henningsen wrote:
> gni@gecko.de (Gunther Nikl)  wrote on 15.03.04 in <20040315112744.GA86063@lorien.int.gecko.de>:
> 
> > #define f1() \
> > ({ register int _d0 __asm("d0"); \
> >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> > "memory"); \    _d0; })
> 
> If the problem is the possibility of returning lvalues from statement  
> expressions, what would happen with the following?
> 
> #define f1() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> "memory"); \    _d0 + 0; })
> 
> (The only change is at the end.)

  No difference, GCC seems to remove the addition.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-16 17:54                         ` Nathan Sidwell
@ 2004-03-17 13:13                           ` Gunther Nikl
  0 siblings, 0 replies; 38+ messages in thread
From: Gunther Nikl @ 2004-03-17 13:13 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: gcc, Jamie Lokier

On Tue, Mar 16, 2004 at 05:54:04PM +0000, Nathan Sidwell wrote:
> Gunther Nikl wrote:
> >On Mon, Mar 15, 2004 at 05:50:36PM +0000, Nathan Sidwell wrote:
> 
> >>(in g++, statement expressions always produce a result 'as-if' by
> >>'return').
> >
> >  Does that mean with g++ it should work? I just tried with 3.3 and it
> >  doesn't.
> It seems that those changes didn't make it to 3.3, but will be in 3.4.
> See PR 11295 for details

  Yes, with g++ 3.4 my testcase showed the expected behaviour.

> >>Perhaps your rewriting of the asm is effectively making the same change.
> >  AFAICT from the discussion so far, even if it works with the nested
> >  s-e's, its still wrong.
> I think the nested s-e's are ok.

  Good.

> >>Your example is IMHO another case of why statement-exprs should return
> >>rvalues!
> >  And then I could use s-e as a function argument as I did?
> only the nested ones,

  Thats fine and no problem. I can make sure that only nested s-e are
  used when returning a value.

> >On Tue, Mar 16, 2004 at 09:12:15AM +0000, Nathan Sidwell wrote:
> >
> >>Having statement expressions silently extend the lifetime of an lvalue
> >>declared within is a great way to trip users up.
> >  Is that "my" problem?
> er, sort of. IMHO it is a bug in the mechanism by which s-e's return
> values, and you have fallen over it by your use of the register asm
> variable.

  Do you think I should file a PR? It seems to be a good idea doing that.

  To avoid the local explict register variable completely: Would it be
  possible to combine an asm() statement (getting all inputs in local
  explicit register variables, no outputs and clobbers) and a C expression
  doing the real call? Thats what I already mentioned in an eralier mail.
  In that case one wouldn't need the local explicit register variable for
  the return value. However, I am not sure that this would work reliable.
  As long as the call comes immediately after the asm (a jump to the real
  call would be ok) it should be fine.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-16 23:10 ` Kai Henningsen
  2004-03-17 10:46   ` Gunther Nikl
@ 2004-03-17 15:36   ` Hans-Peter Nilsson
       [not found]     ` <20040317173042.GA16843@lorien.int.gecko.de>
  1 sibling, 1 reply; 38+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-17 15:36 UTC (permalink / raw)
  To: Kai Henningsen; +Cc: gcc

On Tue, 16 Mar 2004, Kai Henningsen wrote:
> gni@gecko.de (Gunther Nikl)  wrote on 15.03.04 in <20040315112744.GA86063@lorien.int.gecko.de>:
>
> > #define f1() \
> > ({ register int _d0 __asm("d0"); \
> >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> > "memory"); \    _d0; })
>
> If the problem is the possibility of returning lvalues from statement
> expressions, what would happen with the following?
>
> #define f1() \
> ({ register int _d0 __asm("d0"); \
>    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> "memory"); \    _d0 + 0; })
>
> (The only change is at the end.)

That *should work*.  It it doesn't, it's a bug.

brgds, H-P

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

* Re: statement expressions and extended asm bug?
       [not found]         ` <20040318083036.GA18027@lorien.int.gecko.de>
@ 2004-03-18 14:15           ` Hans-Peter Nilsson
  2004-03-18 15:00             ` Gunther Nikl
  0 siblings, 1 reply; 38+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-18 14:15 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: Kai Henningsen, gcc

On Thu, 18 Mar 2004, Gunther Nikl wrote:
> On Wed, Mar 17, 2004 at 12:32:32PM -0500, Hans-Peter Nilsson wrote:
> > On Wed, 17 Mar 2004, Gunther Nikl wrote:
> > > On Wed, Mar 17, 2004 at 10:29:54AM -0500, Hans-Peter Nilsson wrote:
> > > > On Tue, 16 Mar 2004, Kai Henningsen wrote:
> > > > > #define f1() \
> > > > > ({ register int _d0 __asm("d0"); \
> > > > >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> > > > > "memory"); \    _d0 + 0; })
> > > > That *should work*.  It it doesn't, it's a bug.
> > >   It doesn't change anything with either 3.3[.3], 3.4 and 3.5.
> > Please file a bug report if you haven't already done so.
>
>   There is no PR yet. I can file one but I need to know why the above
>   (ret + 0) not changing anything is a bug. Its not obvious for me why
>   this is a bug.

If there's a sequence point between the uses of that expression,
then it's a bug.  It there isn't, I'd agree with Nathan(?) that
it's like an assignment to the same variable in the "parallel"
paths.

I forgot now, but didn't you have an example that used two asms
as above where there was a sequence point, yet the asm in one
expression spilled over into the other?

It's no stranger than "func (a++, a++)" being undefined.

>   FYI, I tried a non-zero add just as test and then it did work.
>
>   BTW, what about this?
>
>     if (f1() == f2())

That's not a sequence point, right?

brgds, H-P

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

* Re: statement expressions and extended asm bug?
  2004-03-18 14:15           ` Hans-Peter Nilsson
@ 2004-03-18 15:00             ` Gunther Nikl
  2004-03-19 15:30               ` Jamie Lokier
  0 siblings, 1 reply; 38+ messages in thread
From: Gunther Nikl @ 2004-03-18 15:00 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: Kai Henningsen, gcc

On Thu, Mar 18, 2004 at 08:22:14AM -0500, Hans-Peter Nilsson wrote:
> On Thu, 18 Mar 2004, Gunther Nikl wrote:
> > On Wed, Mar 17, 2004 at 12:32:32PM -0500, Hans-Peter Nilsson wrote:
> > > On Wed, 17 Mar 2004, Gunther Nikl wrote:
> > > > On Wed, Mar 17, 2004 at 10:29:54AM -0500, Hans-Peter Nilsson wrote:
> > > > > On Tue, 16 Mar 2004, Kai Henningsen wrote:
> > > > > > #define f1() \
> > > > > > ({ register int _d0 __asm("d0"); \
> > > > > >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1", "cc",
> > > > > > "memory"); \    _d0 + 0; })
> > > > > That *should work*.  It it doesn't, it's a bug.
> > > >   It doesn't change anything with either 3.3[.3], 3.4 and 3.5.
> > > Please file a bug report if you haven't already done so.
> >
> >   There is no PR yet. I can file one but I need to know why the above
> >   (ret + 0) not changing anything is a bug. Its not obvious for me why
> >   this is a bug.
> 
> If there's a sequence point between the uses of that expression,
> then it's a bug.  It there isn't, I'd agree with Nathan(?) that
> it's like an assignment to the same variable in the "parallel"
> paths.

  I think that the discussion concluded that there is no sequence
  point, but see below.

> I forgot now, but didn't you have an example that used two asms
> as above where there was a sequence point, yet the asm in one
> expression spilled over into the other?

  Yes, my example used two macros both having a s-e and an extended
  asm which returned a value in an explicit hardreg. According to
  http://gcc.gnu.org/ml/gcc/2004-03/msg00740.html the example has a
  sequence point violation but it shouldn't have one since s-e are
  intended for use in macros function-like macros.

> It's no stranger than "func (a++, a++)" being undefined.

  I know that this has undefined behavoiur.

> >   FYI, I tried a non-zero add just as test and then it did work.
> >
> >   BTW, what about this?
> >
> >     if (f1() == f2())
> 
> That's not a sequence point, right?

  IMHO, if that is a sequence point violation depends also on how s-e
  should behave.

  Gunther

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

* Re: statement expressions and extended asm bug?
  2004-03-18 15:00             ` Gunther Nikl
@ 2004-03-19 15:30               ` Jamie Lokier
  2004-03-19 15:56                 ` Segher Boessenkool
  0 siblings, 1 reply; 38+ messages in thread
From: Jamie Lokier @ 2004-03-19 15:30 UTC (permalink / raw)
  To: Gunther Nikl; +Cc: Hans-Peter Nilsson, Kai Henningsen, gcc

Hans-Peter Nilsson wrote:
> It's no stranger than "func (a++, a++)" being undefined.

That's undefined.  This isn't undefined:

    static inline void increment (int * ptr) { *ptr++; return 0; }
    func (increment (&a), increment (&a));

I'm not sure where this is defined or not, or whether it should be:

    #define increment(ptr) ({ *(ptr)++; 0; })
    func (increment (&a), increment (&a));

-- Jamie

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

* Re: statement expressions and extended asm bug?
  2004-03-19 15:30               ` Jamie Lokier
@ 2004-03-19 15:56                 ` Segher Boessenkool
  2004-03-19 15:58                   ` Segher Boessenkool
                                     ` (2 more replies)
  0 siblings, 3 replies; 38+ messages in thread
From: Segher Boessenkool @ 2004-03-19 15:56 UTC (permalink / raw)
  To: Jamie Lokier; +Cc: Kai Henningsen, gcc, Gunther Nikl, Hans-Peter Nilsson


On 19-mrt-04, at 14:53, Jamie Lokier wrote:

> Hans-Peter Nilsson wrote:
>> It's no stranger than "func (a++, a++)" being undefined.
>
> That's undefined.  This isn't undefined:
>
>     static inline void increment (int * ptr) { *ptr++; return 0; }
>     func (increment (&a), increment (&a));

No, it is just as undefined.  The compiler is free to call
either the "left" or the "right" increment() first.


Segher

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

* Re: statement expressions and extended asm bug?
  2004-03-19 15:56                 ` Segher Boessenkool
@ 2004-03-19 15:58                   ` Segher Boessenkool
  2004-03-19 16:10                     ` Jamie Lokier
  2004-03-19 16:20                   ` Nathan Sidwell
  2004-03-21  8:49                   ` Robert Dewar
  2 siblings, 1 reply; 38+ messages in thread
From: Segher Boessenkool @ 2004-03-19 15:58 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Gunther Nikl, Jamie Lokier, Kai Henningsen, gcc, Hans-Peter Nilsson


On 19-mrt-04, at 15:18, Segher Boessenkool wrote:

>
> On 19-mrt-04, at 14:53, Jamie Lokier wrote:
>
>> Hans-Peter Nilsson wrote:
>>> It's no stranger than "func (a++, a++)" being undefined.
>>
>> That's undefined.  This isn't undefined:
>>
>>     static inline void increment (int * ptr) { *ptr++; return 0; }
>>     func (increment (&a), increment (&a));
>
> No, it is just as undefined.  The compiler is free to call
> either the "left" or the "right" increment() first.

Erm.  Well of course you return 0 in any case, so evaluation order
doesn't change the meaning of this example.  But it's invalid
code anyway, now that I took a second look at it ;-)


Segher

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

* Re: statement expressions and extended asm bug?
  2004-03-19 15:58                   ` Segher Boessenkool
@ 2004-03-19 16:10                     ` Jamie Lokier
  0 siblings, 0 replies; 38+ messages in thread
From: Jamie Lokier @ 2004-03-19 16:10 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Gunther Nikl, Kai Henningsen, gcc, Hans-Peter Nilsson

Segher Boessenkool wrote:
> >>    static inline void increment (int * ptr) { *ptr++; return 0; }
> >>    func (increment (&a), increment (&a));
> >
> >No, it is just as undefined.  The compiler is free to call
> >either the "left" or the "right" increment() first.
> 
> Erm.  Well of course you return 0 in any case, so evaluation order
> doesn't change the meaning of this example.  But it's invalid
> code anyway, now that I took a second look at it ;-)

Oh, typo :)  It should say "static inline int".

-- Jamie

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

* Re: statement expressions and extended asm bug?
  2004-03-19 15:56                 ` Segher Boessenkool
  2004-03-19 15:58                   ` Segher Boessenkool
@ 2004-03-19 16:20                   ` Nathan Sidwell
  2004-03-19 16:25                     ` Segher Boessenkool
  2004-03-21  8:49                   ` Robert Dewar
  2 siblings, 1 reply; 38+ messages in thread
From: Nathan Sidwell @ 2004-03-19 16:20 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Jamie Lokier, Kai Henningsen, gcc, Gunther Nikl, Hans-Peter Nilsson

Segher Boessenkool wrote:
> 
> On 19-mrt-04, at 14:53, Jamie Lokier wrote:
> 
>> Hans-Peter Nilsson wrote:

>> That's undefined.  This isn't undefined:
>>
>>     static inline void increment (int * ptr) { *ptr++; return 0; }
>>     func (increment (&a), increment (&a));

> No, it is just as undefined.  The compiler is free to call
> either the "left" or the "right" increment() first.

Why is this undefined? Isn't it just unspecified? If I understand
the DR Joseph pointed me too, the order of the two function calls
is unspecified, but they do not overlap and there is a sequence point
just before each call (after the arguments have been evaluated), and
a sequence point before each returns.

The original stmt-expr problem is more akin to the following (if stmt-exprs
were to produce rvalues in a return-like way),
   int var;
   static inline int frob (int x) {var = x; return var;}
   func (frob (12), frob (13));
Are you saying this is undefined too?

nathan

-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


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

* Re: statement expressions and extended asm bug?
  2004-03-19 16:20                   ` Nathan Sidwell
@ 2004-03-19 16:25                     ` Segher Boessenkool
  0 siblings, 0 replies; 38+ messages in thread
From: Segher Boessenkool @ 2004-03-19 16:25 UTC (permalink / raw)
  To: Nathan Sidwell
  Cc: Gunther Nikl, Jamie Lokier, Kai Henningsen, gcc, Hans-Peter Nilsson

>>>     static inline void increment (int * ptr) { *ptr++; return 0; }
>>>     func (increment (&a), increment (&a));
>
>> No, it is just as undefined.  The compiler is free to call
>> either the "left" or the "right" increment() first.
>
> Why is this undefined? Isn't it just unspecified? If I understand
> the DR Joseph pointed me too, the order of the two function calls
> is unspecified, but they do not overlap and there is a sequence point
> just before each call (after the arguments have been evaluated), and
> a sequence point before each returns.

Yes, I overlooked the fact that increment() always return 0, instead
of the value of *ptr++.  So either order the arguments to func() are
evaluated, you get the same values, so this is fine.  (with the
obvious s/void/int/ , of course).

It's just the same as

	increment(&a);
	increment(&a);
	func(0, 0);

> The original stmt-expr problem is more akin to the following (if 
> stmt-exprs
> were to produce rvalues in a return-like way),
>   int var;
>   static inline int frob (int x) {var = x; return var;}
>   func (frob (12), frob (13));
> Are you saying this is undefined too?

The return values of the two "calls" to frob() are not
dependent on the order of those calls; so no.

Sorry for the confusion.


Segher

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

* Re: statement expressions and extended asm bug?
  2004-03-17 10:46   ` Gunther Nikl
@ 2004-03-19 22:38     ` Kai Henningsen
  0 siblings, 0 replies; 38+ messages in thread
From: Kai Henningsen @ 2004-03-19 22:38 UTC (permalink / raw)
  To: gcc

gni@gecko.de (Gunther Nikl)  wrote on 17.03.04 in <20040317102933.GA15236@lorien.int.gecko.de>:

> On Tue, Mar 16, 2004 at 09:56:00PM +0200, Kai Henningsen wrote:
> > gni@gecko.de (Gunther Nikl)  wrote on 15.03.04 in
> > <20040315112744.GA86063@lorien.int.gecko.de>:
> >
> > > #define f1() \
> > > ({ register int _d0 __asm("d0"); \
> > >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1",
> > >    "cc",
> > > "memory"); \    _d0; })
> >
> > If the problem is the possibility of returning lvalues from statement
> > expressions, what would happen with the following?
> >
> > #define f1() \
> > ({ register int _d0 __asm("d0"); \
> >    __asm volatile ("moveq #11,d0" : "=r" (_d0) : /**/ : "fp0", "fp1",
> >    "cc",
> > "memory"); \    _d0 + 0; })
> >
> > (The only change is at the end.)
>
>   No difference, GCC seems to remove the addition.

Well, if that doesn't work, then the whole lvalue argument seems to be a  
red herring.

That seems to demonstrate that it is in fact the sequence point thing.

MfG Kai

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

* Re: statement expressions and extended asm bug?
  2004-03-19 15:56                 ` Segher Boessenkool
  2004-03-19 15:58                   ` Segher Boessenkool
  2004-03-19 16:20                   ` Nathan Sidwell
@ 2004-03-21  8:49                   ` Robert Dewar
  2004-03-22 14:57                     ` Segher Boessenkool
  2 siblings, 1 reply; 38+ messages in thread
From: Robert Dewar @ 2004-03-21  8:49 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Jamie Lokier, Kai Henningsen, gcc, Gunther Nikl, Hans-Peter Nilsson

Segher Boessenkool wrote:

>>     static inline void increment (int * ptr) { *ptr++; return 0; }
>>     func (increment (&a), increment (&a));

> No, it is just as undefined.  The compiler is free to call
> either the "left" or the "right" increment() first.

Don't mix up undefined with well defined but non-deterministic
semantics. The function calls in such a case may indeed result
in a non-deterministic semantics (although in this particular
case they don't), but the result is well defined. But the
macro or explicit multiple increment is indeed undefined.
At least that's my understanding of current C semantics!


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

* Re: statement expressions and extended asm bug?
  2004-03-21  8:49                   ` Robert Dewar
@ 2004-03-22 14:57                     ` Segher Boessenkool
  0 siblings, 0 replies; 38+ messages in thread
From: Segher Boessenkool @ 2004-03-22 14:57 UTC (permalink / raw)
  To: Robert Dewar
  Cc: Gunther Nikl, Jamie Lokier, Kai Henningsen, gcc, Hans-Peter Nilsson

> Don't mix up undefined with well defined but non-deterministic
> semantics. The function calls in such a case may indeed result
> in a non-deterministic semantics (although in this particular
> case they don't),

Yes, I overlooked the "return 0", as I wrote already.  So very
very sorry about that.

> but the result is well defined. But the
> macro or explicit multiple increment is indeed undefined.
> At least that's my understanding of current C semantics!

The semantics are not well defined, or at least not uniquely
defined, if you like that term better.  The standard calls it
"unspecified behaviour" I think?

Any program with output depending on unspecified behaviour is
"not strictly conforming", but is a "correct program".

FWIW,


Segher

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

* Re: statement expressions and extended asm bug?
  2004-03-22 15:23 Segher Boessenkool
@ 2004-03-22 16:33 ` Robert Dewar
  0 siblings, 0 replies; 38+ messages in thread
From: Robert Dewar @ 2004-03-22 16:33 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: hp, gni, jamie, gcc, kaih

Segher Boessenkool wrote:

> Agreed.  But I was talking about the _semantics_ of a program, not
> about the program itself.  I'd hate to see a program with
> non-deterministic _semantics_ ;-)

Why? It is quite usual for programs to have non-deterministic
semantics. Indeed this routinely arises in concurrent programs,
and even in sequential programs, it is common in many programming
languages to leave some ordering non-deterministic.

I don't underswtand at all the difference between a program
and the semantics of a program.

Certainly in many higher level languages, you very much want
non-deterministic semantics, e.g. for arbitrary selection from
a set.

And in almost any language you can write a program which reads
the clock to seed the random number generator and achieve
ND semantics.

(note that ND does not imply random, but random does imply ND!)

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

* Re: statement expressions and extended asm bug?
@ 2004-03-22 15:23 Segher Boessenkool
  2004-03-22 16:33 ` Robert Dewar
  0 siblings, 1 reply; 38+ messages in thread
From: Segher Boessenkool @ 2004-03-22 15:23 UTC (permalink / raw)
  To: segher, dewar; +Cc: hp, gni, jamie, gcc, kaih

>> The semantics are not well defined, or at least not uniquely
>> defined, if you like that term better.
>
> I prefer the terms determistic and non-deterministic. You can have
> a program whose result is entirely well defined, but non-determinstic.
> THat's not a problematical concept at all.

Agreed.  But I was talking about the _semantics_ of a program, not
about the program itself.  I'd hate to see a program with
non-deterministic _semantics_ ;-)


Segher

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

* Re: statement expressions and extended asm bug?
@ 2004-03-22 15:05 Robert Dewar
  0 siblings, 0 replies; 38+ messages in thread
From: Robert Dewar @ 2004-03-22 15:05 UTC (permalink / raw)
  To: dewar, segher; +Cc: gcc, gni, hp, jamie, kaih

> The semantics are not well defined, or at least not uniquely
> defined, if you like that term better.

I prefer the terms determistic and non-deterministic. You can have
a program whose result is entirely well defined, but non-determinstic.
THat's not a problematical concept at all.

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

end of thread, other threads:[~2004-03-22 13:25 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-15 11:26 statement expressions and extended asm bug? Gunther Nikl
2004-03-15 11:46 ` Nathan Sidwell
2004-03-15 13:50   ` Gunther Nikl
2004-03-15 14:03     ` Nathan Sidwell
2004-03-15 14:49       ` Gunther Nikl
2004-03-15 15:20         ` Nathan Sidwell
2004-03-15 15:35           ` Gunther Nikl
2004-03-15 15:54             ` Nathan Sidwell
2004-03-15 16:41               ` Gunther Nikl
2004-03-15 17:50                 ` Nathan Sidwell
2004-03-15 20:25                   ` Jamie Lokier
2004-03-15 20:39                     ` Joseph S. Myers
2004-03-15 20:41                     ` Gabriel Dos Reis
2004-03-15 20:52                       ` Jamie Lokier
2004-03-16 14:54                         ` Gunther Nikl
2004-03-16  9:12                     ` Nathan Sidwell
2004-03-16 13:05                       ` Joseph S. Myers
2004-03-16 14:18                       ` Gunther Nikl
2004-03-16 17:54                         ` Nathan Sidwell
2004-03-17 13:13                           ` Gunther Nikl
2004-03-16 23:10 ` Kai Henningsen
2004-03-16 23:10 ` Kai Henningsen
2004-03-17 10:46   ` Gunther Nikl
2004-03-19 22:38     ` Kai Henningsen
2004-03-17 15:36   ` Hans-Peter Nilsson
     [not found]     ` <20040317173042.GA16843@lorien.int.gecko.de>
     [not found]       ` <Pine.BSF.4.58.0403171231350.40025@dair.pair.com>
     [not found]         ` <20040318083036.GA18027@lorien.int.gecko.de>
2004-03-18 14:15           ` Hans-Peter Nilsson
2004-03-18 15:00             ` Gunther Nikl
2004-03-19 15:30               ` Jamie Lokier
2004-03-19 15:56                 ` Segher Boessenkool
2004-03-19 15:58                   ` Segher Boessenkool
2004-03-19 16:10                     ` Jamie Lokier
2004-03-19 16:20                   ` Nathan Sidwell
2004-03-19 16:25                     ` Segher Boessenkool
2004-03-21  8:49                   ` Robert Dewar
2004-03-22 14:57                     ` Segher Boessenkool
2004-03-22 15:05 Robert Dewar
2004-03-22 15:23 Segher Boessenkool
2004-03-22 16:33 ` Robert Dewar

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).