Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 14, 2001 Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: Evaluation order for function parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | 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 > > >> >> > > > >> >> > > > >> >> > > >> >> > > >> > > > >> > > > >> > > >> > > > > > > > > > > > > |
Copyright © 1999-2021 by the D Language Foundation