www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Evaluation order

reply =?iso-8859-1?Q?Miguel_Ferreira_Sim=F5es?= <Kobold netcabo.pt> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hi,
I've been searching the documentation and I found:

"Unless otherwise specified, the implementation is free to evaluate the =
components of an expression in any order. It is an error to depend on =
order of evaluation when it is not specified. For example, the following =
is illegal:    func(++i, ++i)"
   =20
Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

Thanks.

--=20
Miguel Ferreira Simoes
Nov 01 2004
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Miguel Ferreira Simões wrote:

 Hi,
 I've been searching the documentation and I found:
  
 "Unless otherwise specified, the implementation is free to evaluate the 
 components of an expression in any order. It is an error to depend on 
 order of evaluation when it is not specified. For example, the 
 following is illegal:    func(++i, ++i)"
    
 Isn't it supposed to evaluate function parameters from right to left? 
 Isn't it that the c/c++ way?

AIUI the behaviour is undefined in C(++). So if i == 6 before the call, just about any of these could happen: func(7, 8) func(8, 7) func(7, 7) func(8, 8) among maybe others.... D takes the next logical step by defining it to be illegal. The point is to enable certain optimisations, potentially including parallel processing. Stewart.
Nov 01 2004
prev sibling next sibling parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Interesting. Determing a dependency on evaluation order seems like =
something a compiler can't possibly do in all cases. For example it =
might figure out
 func(++i,i++)
but what about
 func(f(),g())
and f and g are function pointers that aren't known at compile-time? Oh =
well. I guess saying the compiler should error out for the simple cases =
is better for the user than just having the behavior undefined. Maybe =
the doc should say some dependencies might not be detected (or =
detectable) by the compiler.
  "Miguel Ferreira Sim=F5es" <Kobold netcabo.pt> wrote in message =
news:cm514a$uf2$1 digitaldaemon.com...
  Hi,
  I've been searching the documentation and I found:

  "Unless otherwise specified, the implementation is free to evaluate =
the components of an expression in any order. It is an error to depend =
on order of evaluation when it is not specified. For example, the =
following is illegal:    func(++i, ++i)"
     =20
  Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

  Thanks.

  --=20
  Miguel Ferreira Simoes
Nov 01 2004
parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Ben Hinkle wrote:

 This is a multi-part message in MIME format.
 
 ------=_NextPart_000_0013_01C4BFF9.E69D7FE0

It helps to post only in plain text. I was catching up over the web interface last night, and it came out quite a mess.
 Interesting. Determing a dependency on evaluation order seems like 
 something a compiler can't possibly do in all cases. For example it 
 might figure out
  func(++i,i++)
 but what about
  func(f(),g())
 and f and g are function pointers that aren't known at compile-time? Oh 
 well. I guess saying the compiler should error out for the simple cases 
 is better for the user than just having the behavior undefined. Maybe 
 the doc should say some dependencies might not be detected (or 
 detectable) by the compiler.

It already does, right below the snippet the OP quoted. http://www.digitalmars.com/d/expression.html "If the compiler can determine that the result of an expression is illegally dependent on the order of evaluation, it can issue an error (but is not required to). The ability to detect these kinds of errors is a quality of implementation issue." Stewart.
Nov 02 2004
prev sibling parent reply Charlie <Charlie_member pathlink.com> writes:
Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

I think its a side-effect of the calling convention __cdecl , __stdcall, __fastcall , __fortran , __pascal . I think it would be cool if we could count on them evaluating left to right , get rid of one more legacy hang up :). Charlie In article <cm514a$uf2$1 digitaldaemon.com>, =?iso-8859-1?Q?Miguel_Ferreira_Sim=F5es?= says...
This is a multi-part message in MIME format.

------=_NextPart_000_0006_01C4BFF8.BE6792F0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hi,
I've been searching the documentation and I found:

"Unless otherwise specified, the implementation is free to evaluate the =
components of an expression in any order. It is an error to depend on =
order of evaluation when it is not specified. For example, the following =
is illegal:    func(++i, ++i)"
   =20
Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

Thanks.

--=20
Miguel Ferreira Simoes
------=_NextPart_000_0006_01C4BFF8.BE6792F0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=3DContent-Type content=3D"text/html; =
charset=3Diso-8859-1">
<META content=3D"MSHTML 6.00.2900.2180" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT face=3DArial size=3D2>Hi,</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>I've been searching the documentation =
and I=20
found:</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>"Unless otherwise specified, the =
implementation is=20
free to evaluate the components of an expression in any order. It is an =
error to=20
depend on order of evaluation when it is not specified. For example, the =

following&nbsp;is illegal:&nbsp;&nbsp;&nbsp; </FONT><FONT face=3DArial=20
size=3D2>func(++i, ++i)"</FONT></DIV>
<DIV><FONT face=3DArial size=3D2>&nbsp;&nbsp;&nbsp; </FONT></DIV>
<DIV><FONT face=3DArial size=3D2>Isn't it supposed to evaluate function =
parameters=20
from right to left? Isn't it that the c/c++ way?</FONT></DIV>
<DIV><FONT face=3DArial size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT face=3DArial size=3D2>Thanks.</FONT></DIV>
<DIV><BR><FONT face=3DArial size=3D2>-- <BR>Miguel Ferreira=20
Simoes</FONT></DIV></BODY></HTML>

------=_NextPart_000_0006_01C4BFF8.BE6792F0--

Nov 01 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Charlie" <Charlie_member pathlink.com> wrote in message
news:cm65bg$l6b$1 digitaldaemon.com...
Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

I think its a side-effect of the calling convention __cdecl , __stdcall, __fastcall , __fortran , __pascal . I think it would be cool if we could

 on them evaluating left to right , get rid of one more legacy hang up :).

The three options on order evaluation are: 1) make it implementation defined 2) make it language defined 3) make it an error (1) is the C/C++ way, and leads to non-portable code and no way to verify that the code is free of OOE defects. (3) is currently what D does, though D cannot get it right 100% of the time. Probably the best answer is (2).
Nov 02 2004
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Walter wrote:
<snip>
 The three options on order evaluation are:
 1) make it implementation defined
 2) make it language defined
 3) make it an error
 
 (1) is the C/C++ way, and leads to non-portable code and no way to verify
 that the code is free of OOE defects. (3) is currently what D does, though D
 cannot get it right 100% of the time. Probably the best answer is (2).

I'm inclined to leave it as (3). That way, optimisations based on this assumption can still take place, even in situations too complex for the compiler to be sure whether there is an order dependence. Anyone who's learned to think in D (and indeed anyone who thinks in C(++) _correctly_) should know to be careful in such situations. You left out (4) make it completely undefined. But then, we probably don't want to go that way.... Stewart.
Nov 05 2004
parent "Walter" <newshound digitalmars.com> writes:
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message
news:cmgf23$1go9$1 digitaldaemon.com...
 Walter wrote:
 <snip>
 The three options on order evaluation are:
 1) make it implementation defined
 2) make it language defined
 3) make it an error

 (1) is the C/C++ way, and leads to non-portable code and no way to


 that the code is free of OOE defects. (3) is currently what D does,


 cannot get it right 100% of the time. Probably the best answer is (2).

I'm inclined to leave it as (3). That way, optimisations based on this assumption can still take place, even in situations too complex for the compiler to be sure whether there is an order dependence.

The problem with (3) is it cannot be properly detected in all, or even most, cases.
 Anyone who's learned to think in D (and indeed anyone who thinks in
 C(++) _correctly_) should know to be careful in such situations.

People aren't careful <g>. It's reasonable to have the language prevent careless mistakes by design as much as practical.
Nov 06 2004
prev sibling parent Burton Radons <burton-radons smocky.com> writes:
Walter wrote:
 "Charlie" <Charlie_member pathlink.com> wrote in message
 news:cm65bg$l6b$1 digitaldaemon.com...
 
Isn't it supposed to evaluate function parameters from right to left? =
Isn't it that the c/c++ way?

I think its a side-effect of the calling convention __cdecl , __stdcall, __fastcall , __fortran , __pascal . I think it would be cool if we could

count
on them evaluating left to right , get rid of one more legacy hang up :).

The three options on order evaluation are: 1) make it implementation defined 2) make it language defined 3) make it an error (1) is the C/C++ way, and leads to non-portable code and no way to verify that the code is free of OOE defects. (3) is currently what D does, though D cannot get it right 100% of the time. Probably the best answer is (2).

It should be noted that when C makes something undefined, it means that the compiler is allowed to reject it as erroneous as there's no way to compile it properly anyway. I think any compiler which has the opportunity to detect an undefined operation and doesn't take it is buggy, although it's a symptom of C's problems in that compilers for it can't reject undefined code by default because it's legacy. I've been leaning on 2 lately, too. It can be optimised around, and register juggling isn't nearly as important as it used to be. I think the optimisation justification is a little unordered; compliance to casual sense should override. It's also inconsistent - a manual inlining gives different capabilities to the optimiser than an automatic inlining. The trouble is that as you said later, it's undetectable in many instances. However, once code does go undefined, any execution of it is wrong. So we have a lot of code which may be undefined and only compiles correctly because compilers have developed an informal standard of how to compile potentially undefined code so that it acts in a predictable manner. I think it would be better for all parties in the end to have the language defined.
Nov 07 2004