Jump to page: 1 2
Thread overview
Evaluation order for function parameters
May 14, 2001
Mark Evans
May 15, 2001
Walter
May 15, 2001
John Fletcher
May 15, 2001
Mark Evans
May 15, 2001
Jan Knepper
May 15, 2001
Walter
May 15, 2001
Mark Evans
May 16, 2001
Walter
May 16, 2001
Mark Evans
May 16, 2001
Walter
May 16, 2001
Mark Evans
May 14, 2001
My question pertains to the order of evaluation of function parameters expressed, in turn, as function calls.

	test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));

I know that C has a convention about the ultimate ordering of parameters on the stack.  That's not what concerns me.
What I need to know is the order of evaluation for barOne(), barTwo(), and barThree().  Is it left-to-right, right-to-left, or something undetermined?

Thanks,

Mark


May 15, 2001
It depends on whether it is a C function, a C++ function, and whether it has cdecl, pascal, fortran, stdcall, linkage.

In other words, it's best to not depend on any particular order, and rewrite as:

    a = barOne(1.0);
    b = barTwo(2.0);
    c = barThree(3.0);
    test = foo(a, b, c);

Now the order of evaluation is guaranteed.


Mark Evans wrote in message <1103_989852553@evans>...
>My question pertains to the order of evaluation of function parameters
expressed, in turn, as function calls.
>
> test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
>
>I know that C has a convention about the ultimate ordering of parameters on
the stack.  That's not what concerns me.
>What I need to know is the order of evaluation for barOne(), barTwo(), and
barThree().  Is it left-to-right, right-to-left, or something undetermined?
>
>Thanks,
>
>Mark
>
>


May 15, 2001

Walter wrote:

> It depends on whether it is a C function, a C++ function, and whether it has cdecl, pascal, fortran, stdcall, linkage.
>
> In other words, it's best to not depend on any particular order, and rewrite as:
>
>     a = barOne(1.0);
>     b = barTwo(2.0);
>     c = barThree(3.0);
>     test = foo(a, b, c);
>
> Now the order of evaluation is guaranteed.
>

I met a similar problem once with some code which went:

x[i] = y[i--];

and the writer had assumed that the -- would take place after the assignment. This was hidden in a macro! It worked for some compilers but not others. I replaced it with this:

x[i] = y[i]; i--;

John



May 15, 2001
It may be best, but is not always desirable to do that.  In some applications the whole idea is to avoid using intermediate variables such as a,b,c in your example.  Instead I have a pseudo-
class to perform intermediary functions.  It has standard interface calls and these are what I wish to employ.  The pseudo-class serves the purpose of simplifying calls made to a DLL.  The
last thing I want to do is rewrite 186 DLL calls using intermediate variables for each parameter.  That was why I wrote the pseudo-class.  I got tired of using intermediate dummy variables.
The class takes user parameters from an input text stream and turns them into DLL calls.  I want the pseudo-class interface calls embedded in the DLL function call code.  A working
example:

WRAP( spmCalSync )
{
	static TypeCode types_in[]  = {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
	static TypeCode types_out[] = {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};

	DEFAULT_PARSE;

	*Next_SPMERR(outpb,PUT) =
	spmCalSynch(
		*Pop_SPMHANDLE(inpb),
		Next_SPMHANDLE(outpb,PUT),
		*Pop_I32(inpb),
		BLCTruth(*Pop_BLC(inpb)));

	DEFAULT_FORMAT;
}

where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very easy to read and to write.  All it takes is a little care with the compiler evaluation ordering.  The code implements a form of run-time type information in procedural C.

Some simple testing has revealed what I needed to know.  In procedural C the evaluation order is right-to-left, same as the stack order.  I haven't tested C++ but would assume it's the same.

It would be nice if the documentation covered this topic since in principle, the evaluation order need not correspond to the stack order, although it does in this case.

Mark


On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com> wrote:
> It depends on whether it is a C function, a C++ function, and whether it has cdecl, pascal, fortran, stdcall, linkage.
> 
> In other words, it's best to not depend on any particular order, and rewrite as:
> 
>     a = barOne(1.0);
>     b = barTwo(2.0);
>     c = barThree(3.0);
>     test = foo(a, b, c);
> 
> Now the order of evaluation is guaranteed.
> 
> 
> Mark Evans wrote in message <1103_989852553@evans>...
> >My question pertains to the order of evaluation of function parameters
> expressed, in turn, as function calls.
> >
> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
> >
> >I know that C has a convention about the ultimate ordering of parameters on
> the stack.  That's not what concerns me.
> >What I need to know is the order of evaluation for barOne(), barTwo(), and
> barThree().  Is it left-to-right, right-to-left, or something undetermined?
> >
> >Thanks,
> >
> >Mark
> >
> >
> 
> 


May 15, 2001
Mark,

I think it is basically as Walter wrote.
When you use __cdecl in your function prototype you define the function to be C prototype which basically means that the last function argument is put on the stack first. This has to be this way
as after all the arguments have been put on the stack the return address will be put on the stack. (Of course 'call' does that for you). So when digging the stack in the *called* function you
know that the first argument appears closest to the return address. This way it is possible to have functions wth a variable number of arguments as long as there is some way to tell the function
how meny arguments there are. This way a printf can exist and quite a few more like that.

I actually recently implemented a vsscanf as it seems to be missing in the standard libraries.

Don't worry, be Kneppie!
Jan



Mark Evans wrote:

> It may be best, but is not always desirable to do that.  In some applications the whole idea is to avoid using intermediate variables such as a,b,c in your example.  Instead I have a pseudo-
> class to perform intermediary functions.  It has standard interface calls and these are what I wish to employ.  The pseudo-class serves the purpose of simplifying calls made to a DLL.  The
> last thing I want to do is rewrite 186 DLL calls using intermediate variables for each parameter.  That was why I wrote the pseudo-class.  I got tired of using intermediate dummy variables.
> The class takes user parameters from an input text stream and turns them into DLL calls.  I want the pseudo-class interface calls embedded in the DLL function call code.  A working
> example:
>
> WRAP( spmCalSync )
> {
>         static TypeCode types_in[]  = {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
>         static TypeCode types_out[] = {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
>
>         DEFAULT_PARSE;
>
>         *Next_SPMERR(outpb,PUT) =
>         spmCalSynch(
>                 *Pop_SPMHANDLE(inpb),
>                 Next_SPMHANDLE(outpb,PUT),
>                 *Pop_I32(inpb),
>                 BLCTruth(*Pop_BLC(inpb)));
>
>         DEFAULT_FORMAT;
> }
>
> where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very
> easy to read and to write.  All it takes is a little care with the compiler evaluation ordering.  The code implements a form of run-time type information in procedural C.
>
> Some simple testing has revealed what I needed to know.  In procedural C the evaluation order is right-to-left, same as the stack order.  I haven't tested C++ but would assume it's the same.
>
> It would be nice if the documentation covered this topic since in principle, the evaluation order need not correspond to the stack order, although it does in this case.
>
> Mark
>
> On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com> wrote:
> > It depends on whether it is a C function, a C++ function, and whether it has cdecl, pascal, fortran, stdcall, linkage.
> >
> > In other words, it's best to not depend on any particular order, and rewrite as:
> >
> >     a = barOne(1.0);
> >     b = barTwo(2.0);
> >     c = barThree(3.0);
> >     test = foo(a, b, c);
> >
> > Now the order of evaluation is guaranteed.
> >
> >
> > Mark Evans wrote in message <1103_989852553@evans>...
> > >My question pertains to the order of evaluation of function parameters
> > expressed, in turn, as function calls.
> > >
> > > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
> > >
> > >I know that C has a convention about the ultimate ordering of parameters on
> > the stack.  That's not what concerns me.
> > >What I need to know is the order of evaluation for barOne(), barTwo(), and
> > barThree().  Is it left-to-right, right-to-left, or something undetermined?
> > >
> > >Thanks,
> > >
> > >Mark
> > >
> > >
> >
> >

May 15, 2001
Although the DMC compiler does not do this, it would be standard conforming if the optimizer decided to rearrange the order of evaluation of function parameters. So, when you depend on order-of-evaluation, there's a risk that the code may subtly break with different compilers, a different release of the same one *or even* it may change depending on what expressions you use for the parameters and how they interact with the optimizer.

-Walter

Mark Evans wrote in message <1103_989929526@evans>...
>It may be best, but is not always desirable to do that.  In some
applications the whole idea is to avoid using intermediate variables such as a,b,c in your example.  Instead I have a pseudo-
>class to perform intermediary functions.  It has standard interface calls
and these are what I wish to employ.  The pseudo-class serves the purpose of simplifying calls made to a DLL.  The
>last thing I want to do is rewrite 186 DLL calls using intermediate
variables for each parameter.  That was why I wrote the pseudo-class.  I got tired of using intermediate dummy variables.
>The class takes user parameters from an input text stream and turns them
into DLL calls.  I want the pseudo-class interface calls embedded in the DLL function call code.  A working
>example:
>
>WRAP( spmCalSync )
>{
> static TypeCode types_in[]  =
{kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
> static TypeCode types_out[] =
{kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
>
> DEFAULT_PARSE;
>
> *Next_SPMERR(outpb,PUT) =
> spmCalSynch(
> *Pop_SPMHANDLE(inpb),
> Next_SPMHANDLE(outpb,PUT),
> *Pop_I32(inpb),
> BLCTruth(*Pop_BLC(inpb)));
>
> DEFAULT_FORMAT;
>}
>
>where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for
various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very
>easy to read and to write.  All it takes is a little care with the compiler
evaluation ordering.  The code implements a form of run-time type information in procedural C.
>
>Some simple testing has revealed what I needed to know.  In procedural C
the evaluation order is right-to-left, same as the stack order.  I haven't tested C++ but would assume it's the same.
>
>It would be nice if the documentation covered this topic since in
principle, the evaluation order need not correspond to the stack order, although it does in this case.
>
>Mark
>
>
>On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com>
wrote:
>> It depends on whether it is a C function, a C++ function, and whether it
has
>> cdecl, pascal, fortran, stdcall, linkage.
>>
>> In other words, it's best to not depend on any particular order, and
rewrite
>> as:
>>
>>     a = barOne(1.0);
>>     b = barTwo(2.0);
>>     c = barThree(3.0);
>>     test = foo(a, b, c);
>>
>> Now the order of evaluation is guaranteed.
>>
>>
>> Mark Evans wrote in message <1103_989852553@evans>...
>> >My question pertains to the order of evaluation of function parameters
>> expressed, in turn, as function calls.
>> >
>> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
>> >
>> >I know that C has a convention about the ultimate ordering of parameters
on
>> the stack.  That's not what concerns me.
>> >What I need to know is the order of evaluation for barOne(), barTwo(),
and
>> barThree().  Is it left-to-right, right-to-left, or something
undetermined?
>> >
>> >Thanks,
>> >
>> >Mark
>> >
>> >
>>
>>
>
>


May 15, 2001
Walter,

Yes that is what I said, the order of evaluation need not conform to parameter stack order.  That is the reason I asked in the first place.

Agreed it is risky, but as always, no risk, no reward.

Might I suggest the idea of a #pragma to enforce the order of evaluation, thus avoiding the risks?  Perhaps compiler writers could offer programmers a little more control in this area.

Mark


On Tue, 15 May 2001 08:53:40 -0700, "Walter" <walter@digitalmars.com> wrote:
> Although the DMC compiler does not do this, it would be standard conforming if the optimizer decided to rearrange the order of evaluation of function parameters. So, when you depend on order-of-evaluation, there's a risk that the code may subtly break with different compilers, a different release of the same one *or even* it may change depending on what expressions you use for the parameters and how they interact with the optimizer.
> 
> -Walter
> 
> Mark Evans wrote in message <1103_989929526@evans>...
> >It may be best, but is not always desirable to do that.  In some
> applications the whole idea is to avoid using intermediate variables such as a,b,c in your example.  Instead I have a pseudo-
> >class to perform intermediary functions.  It has standard interface calls
> and these are what I wish to employ.  The pseudo-class serves the purpose of simplifying calls made to a DLL.  The
> >last thing I want to do is rewrite 186 DLL calls using intermediate
> variables for each parameter.  That was why I wrote the pseudo-class.  I got tired of using intermediate dummy variables.
> >The class takes user parameters from an input text stream and turns them
> into DLL calls.  I want the pseudo-class interface calls embedded in the DLL function call code.  A working
> >example:
> >
> >WRAP( spmCalSync )
> >{
> > static TypeCode types_in[]  =
> {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
> > static TypeCode types_out[] =
> {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
> >
> > DEFAULT_PARSE;
> >
> > *Next_SPMERR(outpb,PUT) =
> > spmCalSynch(
> > *Pop_SPMHANDLE(inpb),
> > Next_SPMHANDLE(outpb,PUT),
> > *Pop_I32(inpb),
> > BLCTruth(*Pop_BLC(inpb)));
> >
> > DEFAULT_FORMAT;
> >}
> >
> >where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for
> various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very
> >easy to read and to write.  All it takes is a little care with the compiler
> evaluation ordering.  The code implements a form of run-time type information in procedural C.
> >
> >Some simple testing has revealed what I needed to know.  In procedural C
> the evaluation order is right-to-left, same as the stack order.  I haven't tested C++ but would assume it's the same.
> >
> >It would be nice if the documentation covered this topic since in
> principle, the evaluation order need not correspond to the stack order, although it does in this case.
> >
> >Mark
> >
> >
> >On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com>
> wrote:
> >> It depends on whether it is a C function, a C++ function, and whether it
> has
> >> cdecl, pascal, fortran, stdcall, linkage.
> >>
> >> In other words, it's best to not depend on any particular order, and
> rewrite
> >> as:
> >>
> >>     a = barOne(1.0);
> >>     b = barTwo(2.0);
> >>     c = barThree(3.0);
> >>     test = foo(a, b, c);
> >>
> >> Now the order of evaluation is guaranteed.
> >>
> >>
> >> Mark Evans wrote in message <1103_989852553@evans>...
> >> >My question pertains to the order of evaluation of function parameters
> >> expressed, in turn, as function calls.
> >> >
> >> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
> >> >
> >> >I know that C has a convention about the ultimate ordering of parameters
> on
> >> the stack.  That's not what concerns me.
> >> >What I need to know is the order of evaluation for barOne(), barTwo(),
> and
> >> barThree().  Is it left-to-right, right-to-left, or something
> undetermined?
> >> >
> >> >Thanks,
> >> >
> >> >Mark
> >> >
> >> >
> >>
> >>
> >
> >
> 
> 


May 16, 2001
The pragma is a good idea, but the problem I have is that already there are too many options for code generation such that it is a mathematical impossibility to test every combination of options. This makes it a tough sell to add more <g>.

-Walter


Mark Evans wrote in message <1103_989939560@evans>...
>Walter,
>
>Yes that is what I said, the order of evaluation need not conform to
parameter stack order.  That is the reason I asked in the first place.
>
>Agreed it is risky, but as always, no risk, no reward.
>
>Might I suggest the idea of a #pragma to enforce the order of evaluation,
thus avoiding the risks?  Perhaps compiler writers could offer programmers a
>little more control in this area.
>
>Mark
>
>
>On Tue, 15 May 2001 08:53:40 -0700, "Walter" <walter@digitalmars.com>
wrote:
>> Although the DMC compiler does not do this, it would be standard
conforming
>> if the optimizer decided to rearrange the order of evaluation of function parameters. So, when you depend on order-of-evaluation, there's a risk
that
>> the code may subtly break with different compilers, a different release
of
>> the same one *or even* it may change depending on what expressions you
use
>> for the parameters and how they interact with the optimizer.
>>
>> -Walter
>>
>> Mark Evans wrote in message <1103_989929526@evans>...
>> >It may be best, but is not always desirable to do that.  In some
>> applications the whole idea is to avoid using intermediate variables such
as
>> a,b,c in your example.  Instead I have a pseudo-
>> >class to perform intermediary functions.  It has standard interface
calls
>> and these are what I wish to employ.  The pseudo-class serves the purpose
of
>> simplifying calls made to a DLL.  The
>> >last thing I want to do is rewrite 186 DLL calls using intermediate
>> variables for each parameter.  That was why I wrote the pseudo-class.  I
got
>> tired of using intermediate dummy variables.
>> >The class takes user parameters from an input text stream and turns them
>> into DLL calls.  I want the pseudo-class interface calls embedded in the
DLL
>> function call code.  A working
>> >example:
>> >
>> >WRAP( spmCalSync )
>> >{
>> > static TypeCode types_in[]  =
>> {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
>> > static TypeCode types_out[] =
>> {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
>> >
>> > DEFAULT_PARSE;
>> >
>> > *Next_SPMERR(outpb,PUT) =
>> > spmCalSynch(
>> > *Pop_SPMHANDLE(inpb),
>> > Next_SPMHANDLE(outpb,PUT),
>> > *Pop_I32(inpb),
>> > BLCTruth(*Pop_BLC(inpb)));
>> >
>> > DEFAULT_FORMAT;
>> >}
>> >
>> >where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for
>> various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very
>> >easy to read and to write.  All it takes is a little care with the
compiler
>> evaluation ordering.  The code implements a form of run-time type information in procedural C.
>> >
>> >Some simple testing has revealed what I needed to know.  In procedural C
>> the evaluation order is right-to-left, same as the stack order.  I
haven't
>> tested C++ but would assume it's the same.
>> >
>> >It would be nice if the documentation covered this topic since in
>> principle, the evaluation order need not correspond to the stack order, although it does in this case.
>> >
>> >Mark
>> >
>> >
>> >On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com>
>> wrote:
>> >> It depends on whether it is a C function, a C++ function, and whether
it
>> has
>> >> cdecl, pascal, fortran, stdcall, linkage.
>> >>
>> >> In other words, it's best to not depend on any particular order, and
>> rewrite
>> >> as:
>> >>
>> >>     a = barOne(1.0);
>> >>     b = barTwo(2.0);
>> >>     c = barThree(3.0);
>> >>     test = foo(a, b, c);
>> >>
>> >> Now the order of evaluation is guaranteed.
>> >>
>> >>
>> >> Mark Evans wrote in message <1103_989852553@evans>...
>> >> >My question pertains to the order of evaluation of function
parameters
>> >> expressed, in turn, as function calls.
>> >> >
>> >> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
>> >> >
>> >> >I know that C has a convention about the ultimate ordering of
parameters
>> on
>> >> the stack.  That's not what concerns me.
>> >> >What I need to know is the order of evaluation for barOne(),
barTwo(),
>> and
>> >> barThree().  Is it left-to-right, right-to-left, or something
>> undetermined?
>> >> >
>> >> >Thanks,
>> >> >
>> >> >Mark
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >
>>
>>
>
>


May 16, 2001
If not a #pragma then how about a hardwired preprocessor #define (similar to __FILE__ or __cplusplus) which specifies the ordering.  Then I could do

#ifndef __RTL_ARG_EVAL__
#abort "This code requires a particular evaluation order for arguments."
#endif

or something similar to that.  Maybe the C standards folks would be interested in adding it to their list of hardwired #defines, if they have any.

Mark


On Wed, 16 May 2001 00:50:55 -0700, "Walter" <walter@digitalmars.com> wrote:
> The pragma is a good idea, but the problem I have is that already there are too many options for code generation such that it is a mathematical impossibility to test every combination of options. This makes it a tough sell to add more <g>.
> 
> -Walter
> 
> 
> Mark Evans wrote in message <1103_989939560@evans>...
> >Walter,
> >
> >Yes that is what I said, the order of evaluation need not conform to
> parameter stack order.  That is the reason I asked in the first place.
> >
> >Agreed it is risky, but as always, no risk, no reward.
> >
> >Might I suggest the idea of a #pragma to enforce the order of evaluation,
> thus avoiding the risks?  Perhaps compiler writers could offer programmers a
> >little more control in this area.
> >
> >Mark
> >
> >
> >On Tue, 15 May 2001 08:53:40 -0700, "Walter" <walter@digitalmars.com>
> wrote:
> >> Although the DMC compiler does not do this, it would be standard
> conforming
> >> if the optimizer decided to rearrange the order of evaluation of function parameters. So, when you depend on order-of-evaluation, there's a risk
> that
> >> the code may subtly break with different compilers, a different release
> of
> >> the same one *or even* it may change depending on what expressions you
> use
> >> for the parameters and how they interact with the optimizer.
> >>
> >> -Walter
> >>
> >> Mark Evans wrote in message <1103_989929526@evans>...
> >> >It may be best, but is not always desirable to do that.  In some
> >> applications the whole idea is to avoid using intermediate variables such
> as
> >> a,b,c in your example.  Instead I have a pseudo-
> >> >class to perform intermediary functions.  It has standard interface
> calls
> >> and these are what I wish to employ.  The pseudo-class serves the purpose
> of
> >> simplifying calls made to a DLL.  The
> >> >last thing I want to do is rewrite 186 DLL calls using intermediate
> >> variables for each parameter.  That was why I wrote the pseudo-class.  I
> got
> >> tired of using intermediate dummy variables.
> >> >The class takes user parameters from an input text stream and turns them
> >> into DLL calls.  I want the pseudo-class interface calls embedded in the
> DLL
> >> function call code.  A working
> >> >example:
> >> >
> >> >WRAP( spmCalSync )
> >> >{
> >> > static TypeCode types_in[]  =
> >> {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
> >> > static TypeCode types_out[] =
> >> {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
> >> >
> >> > DEFAULT_PARSE;
> >> >
> >> > *Next_SPMERR(outpb,PUT) =
> >> > spmCalSynch(
> >> > *Pop_SPMHANDLE(inpb),
> >> > Next_SPMHANDLE(outpb,PUT),
> >> > *Pop_I32(inpb),
> >> > BLCTruth(*Pop_BLC(inpb)));
> >> >
> >> > DEFAULT_FORMAT;
> >> >}
> >> >
> >> >where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros for
> >> various mundane housekeeping tasks.  The DLL call is "spmCalSynch".  This type of code is very
> >> >easy to read and to write.  All it takes is a little care with the
> compiler
> >> evaluation ordering.  The code implements a form of run-time type information in procedural C.
> >> >
> >> >Some simple testing has revealed what I needed to know.  In procedural C
> >> the evaluation order is right-to-left, same as the stack order.  I
> haven't
> >> tested C++ but would assume it's the same.
> >> >
> >> >It would be nice if the documentation covered this topic since in
> >> principle, the evaluation order need not correspond to the stack order, although it does in this case.
> >> >
> >> >Mark
> >> >
> >> >
> >> >On Mon, 14 May 2001 22:54:23 -0700, "Walter" <walter@digitalmars.com>
> >> wrote:
> >> >> It depends on whether it is a C function, a C++ function, and whether
> it
> >> has
> >> >> cdecl, pascal, fortran, stdcall, linkage.
> >> >>
> >> >> In other words, it's best to not depend on any particular order, and
> >> rewrite
> >> >> as:
> >> >>
> >> >>     a = barOne(1.0);
> >> >>     b = barTwo(2.0);
> >> >>     c = barThree(3.0);
> >> >>     test = foo(a, b, c);
> >> >>
> >> >> Now the order of evaluation is guaranteed.
> >> >>
> >> >>
> >> >> Mark Evans wrote in message <1103_989852553@evans>...
> >> >> >My question pertains to the order of evaluation of function
> parameters
> >> >> expressed, in turn, as function calls.
> >> >> >
> >> >> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
> >> >> >
> >> >> >I know that C has a convention about the ultimate ordering of
> parameters
> >> on
> >> >> the stack.  That's not what concerns me.
> >> >> >What I need to know is the order of evaluation for barOne(),
> barTwo(),
> >> and
> >> >> barThree().  Is it left-to-right, right-to-left, or something
> >> undetermined?
> >> >> >
> >> >> >Thanks,
> >> >> >
> >> >> >Mark
> >> >> >
> >> >> >
> >> >>
> >> >>
> >> >
> >> >
> >>
> >>
> >
> >
> 
> 


May 16, 2001
Since the evaluation order is dependent on many things, and may change from function to function even in the same source file, setting a #define won't help (since the #define would be global).

I understand what you're trying to do, and know that the temporary approach looks ugly. But a lot of things that work wind up looking ugly <g>, and my best recommendation is to just use it. If your code exists for any long period of time (and I've found bits of code I wrote 20 years ago floating around the internet!), might as well be pragmatic about it. At the very least, put a comment in saying it is order dependent.

P.S. If I'd known at the time my source code would be in use 20 years later, I would have written it better <g>. Some of it is embarassingly bad.


"Mark Evans" <mevans@zyvex.com> wrote in message news:1103_990029668@evans...
> If not a #pragma then how about a hardwired preprocessor #define (similar
to __FILE__ or __cplusplus) which specifies the ordering.  Then I could do
>
> #ifndef __RTL_ARG_EVAL__
> #abort "This code requires a particular evaluation order for arguments."
> #endif
>
> or something similar to that.  Maybe the C standards folks would be
interested in adding it to their list of hardwired #defines, if they have any.
>
> Mark
>
>
> On Wed, 16 May 2001 00:50:55 -0700, "Walter" <walter@digitalmars.com>
wrote:
> > The pragma is a good idea, but the problem I have is that already there
are
> > too many options for code generation such that it is a mathematical impossibility to test every combination of options. This makes it a
tough
> > sell to add more <g>.
> >
> > -Walter
> >
> >
> > Mark Evans wrote in message <1103_989939560@evans>...
> > >Walter,
> > >
> > >Yes that is what I said, the order of evaluation need not conform to
> > parameter stack order.  That is the reason I asked in the first place.
> > >
> > >Agreed it is risky, but as always, no risk, no reward.
> > >
> > >Might I suggest the idea of a #pragma to enforce the order of
evaluation,
> > thus avoiding the risks?  Perhaps compiler writers could offer
programmers a
> > >little more control in this area.
> > >
> > >Mark
> > >
> > >
> > >On Tue, 15 May 2001 08:53:40 -0700, "Walter" <walter@digitalmars.com>
> > wrote:
> > >> Although the DMC compiler does not do this, it would be standard
> > conforming
> > >> if the optimizer decided to rearrange the order of evaluation of
function
> > >> parameters. So, when you depend on order-of-evaluation, there's a
risk
> > that
> > >> the code may subtly break with different compilers, a different
release
> > of
> > >> the same one *or even* it may change depending on what expressions
you
> > use
> > >> for the parameters and how they interact with the optimizer.
> > >>
> > >> -Walter
> > >>
> > >> Mark Evans wrote in message <1103_989929526@evans>...
> > >> >It may be best, but is not always desirable to do that.  In some
> > >> applications the whole idea is to avoid using intermediate variables
such
> > as
> > >> a,b,c in your example.  Instead I have a pseudo-
> > >> >class to perform intermediary functions.  It has standard interface
> > calls
> > >> and these are what I wish to employ.  The pseudo-class serves the
purpose
> > of
> > >> simplifying calls made to a DLL.  The
> > >> >last thing I want to do is rewrite 186 DLL calls using intermediate
> > >> variables for each parameter.  That was why I wrote the pseudo-class.
I
> > got
> > >> tired of using intermediate dummy variables.
> > >> >The class takes user parameters from an input text stream and turns
them
> > >> into DLL calls.  I want the pseudo-class interface calls embedded in
the
> > DLL
> > >> function call code.  A working
> > >> >example:
> > >> >
> > >> >WRAP( spmCalSync )
> > >> >{
> > >> > static TypeCode types_in[]  =
> > >> {kTYPE_SPMHANDLE,kTYPE_I32,kTYPE_BOOLCHAR,kTYPE_TERMINATION};
> > >> > static TypeCode types_out[] =
> > >> {kTYPE_SPMERR,kTYPE_SPMHANDLE,kTYPE_TERMINATION};
> > >> >
> > >> > DEFAULT_PARSE;
> > >> >
> > >> > *Next_SPMERR(outpb,PUT) =
> > >> > spmCalSynch(
> > >> > *Pop_SPMHANDLE(inpb),
> > >> > Next_SPMHANDLE(outpb,PUT),
> > >> > *Pop_I32(inpb),
> > >> > BLCTruth(*Pop_BLC(inpb)));
> > >> >
> > >> > DEFAULT_FORMAT;
> > >> >}
> > >> >
> > >> >where WRAP, DEFAULT_PARSE, DEFAULT_FORMAT are preprocessor macros
for
> > >> various mundane housekeeping tasks.  The DLL call is "spmCalSynch".
This
> > >> type of code is very
> > >> >easy to read and to write.  All it takes is a little care with the
> > compiler
> > >> evaluation ordering.  The code implements a form of run-time type information in procedural C.
> > >> >
> > >> >Some simple testing has revealed what I needed to know.  In
procedural C
> > >> the evaluation order is right-to-left, same as the stack order.  I
> > haven't
> > >> tested C++ but would assume it's the same.
> > >> >
> > >> >It would be nice if the documentation covered this topic since in
> > >> principle, the evaluation order need not correspond to the stack
order,
> > >> although it does in this case.
> > >> >
> > >> >Mark
> > >> >
> > >> >
> > >> >On Mon, 14 May 2001 22:54:23 -0700, "Walter"
<walter@digitalmars.com>
> > >> wrote:
> > >> >> It depends on whether it is a C function, a C++ function, and
whether
> > it
> > >> has
> > >> >> cdecl, pascal, fortran, stdcall, linkage.
> > >> >>
> > >> >> In other words, it's best to not depend on any particular order,
and
> > >> rewrite
> > >> >> as:
> > >> >>
> > >> >>     a = barOne(1.0);
> > >> >>     b = barTwo(2.0);
> > >> >>     c = barThree(3.0);
> > >> >>     test = foo(a, b, c);
> > >> >>
> > >> >> Now the order of evaluation is guaranteed.
> > >> >>
> > >> >>
> > >> >> Mark Evans wrote in message <1103_989852553@evans>...
> > >> >> >My question pertains to the order of evaluation of function
> > parameters
> > >> >> expressed, in turn, as function calls.
> > >> >> >
> > >> >> > test = foo(barOne(1.0),barTwo(2.0),barThree(3.0));
> > >> >> >
> > >> >> >I know that C has a convention about the ultimate ordering of
> > parameters
> > >> on
> > >> >> the stack.  That's not what concerns me.
> > >> >> >What I need to know is the order of evaluation for barOne(),
> > barTwo(),
> > >> and
> > >> >> barThree().  Is it left-to-right, right-to-left, or something
> > >> undetermined?
> > >> >> >
> > >> >> >Thanks,
> > >> >> >
> > >> >> >Mark
> > >> >> >
> > >> >> >
> > >> >>
> > >> >>
> > >> >
> > >> >
> > >>
> > >>
> > >
> > >
> >
> >
>
>


« First   ‹ Prev
1 2