public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Function Argument Evaluation
@ 2006-12-06 15:48 Brian D. McGrew
  2006-12-06 15:59 ` John Love-Jensen
  2006-12-06 16:00 ` Daniel Llorens del Río
  0 siblings, 2 replies; 9+ messages in thread
From: Brian D. McGrew @ 2006-12-06 15:48 UTC (permalink / raw)
  To: gcc-help

Good morning,

Historically it's always been that arguments passed into functions get
evaluated from left to right

Ie. 'int foo(int a, char *b, float c) { }

But I'm noticing that with gcc-4.1.1 (on Fedora Core 5), that does not
seem to be the case.  We have some code, granted it may be fragile or
broken code, that relies on the arguments being evaluated from left to
right and seems like that's not the case.  In my code the arguments seem
to be being evaluated right to left.  

Is this by design, a bug, something I'm missing or maybe the optimizer
trying to just be smart???

> :b!

--
Brian D. McGrew        { brian@visionpro.com ||
brian@doubledimension.com }

> You might be a redneck if ...
> You've ever used jumper cables to start your washing machine!



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

* Re: Function Argument Evaluation
  2006-12-06 15:48 Function Argument Evaluation Brian D. McGrew
@ 2006-12-06 15:59 ` John Love-Jensen
  2006-12-06 16:00 ` Daniel Llorens del Río
  1 sibling, 0 replies; 9+ messages in thread
From: John Love-Jensen @ 2006-12-06 15:59 UTC (permalink / raw)
  To: Brian D. McGrew, MSX to GCC

Hi Brian,

There is no guarantee whatsoever as to the order of evaluation of arguments
passed into functions.

int i = 0;
Foo(++i, ++i, ++i); // Foo(1,2,3)? Foo(3,2,1)? Foo(3,3,3)? Other...?

You can't even rely on seemingly identical steps having same order of
evaluation.

int i = 0;
int j = 0;
Foo(++i, ++i, ++i); // e.g., Foo(1,2,3);
Foo(++j, ++j, ++j); // e.g., Foo(2,3,1); Surprise!

If your code relies on particular order-of-evaluation, break out those
evaluations into separate lines of code and use explicit variables to hold
the result which are passed into the function.

I was bit by this back in the 80's when I got my first optimizing compiler.

HTH,
--Eljay

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

* Re: Function Argument Evaluation
  2006-12-06 15:48 Function Argument Evaluation Brian D. McGrew
  2006-12-06 15:59 ` John Love-Jensen
@ 2006-12-06 16:00 ` Daniel Llorens del Río
  2006-12-06 16:21   ` Young, Michael
  1 sibling, 1 reply; 9+ messages in thread
From: Daniel Llorens del Río @ 2006-12-06 16:00 UTC (permalink / raw)
  To: gcc-help


On 6 Dec, 2006, at 16:48, Brian D. McGrew wrote:

> Good morning,
>
> Historically it's always been that arguments passed into functions get
> evaluated from left to right

Not true.

> Ie. 'int foo(int a, char *b, float c) { }
>
> But I'm noticing that with gcc-4.1.1 (on Fedora Core 5), that does not
> seem to be the case.  We have some code, granted it may be fragile or
> broken code, that relies on the arguments being evaluated from left to
> right and seems like that's not the case.  In my code the arguments  
> seem
> to be being evaluated right to left.

I /think/ that with -O0 the arguments are evaluated left to right.  
However, neither the standards nor gcc make any guarantee about  
argument evaluation order. Not now and not historically either. Any  
code that relies on a particular order of evaluation is broken.

You've just been lucky (or not, depending on the point of view) up to  
now. It is typical that such bugs are exposed when the optimization  
level is changed, which is a good reason to test regularly with both - 
O0 and -O2.


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

* RE: Function Argument Evaluation
  2006-12-06 16:00 ` Daniel Llorens del Río
@ 2006-12-06 16:21   ` Young, Michael
  2006-12-06 16:43     ` Daniel Llorens del Río
                       ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Young, Michael @ 2006-12-06 16:21 UTC (permalink / raw)
  To: Daniel Llorens del Río, gcc-help

>> Good morning,
>>
>> Historically it's always been that arguments passed into functions get
>> evaluated from left to right
>
>Not true.
>
>> Ie. 'int foo(int a, char *b, float c) { }
>>
>> But I'm noticing that with gcc-4.1.1 (on Fedora Core 5), that does not
>> seem to be the case.  We have some code, granted it may be fragile or
>> broken code, that relies on the arguments being evaluated from left to
>> right and seems like that's not the case.  In my code the arguments  
>> seem
>> to be being evaluated right to left.
>
>I /think/ that with -O0 the arguments are evaluated left to right.  
>However, neither the standards nor gcc make any guarantee about  
>argument evaluation order. Not now and not historically either. Any  
>code that relies on a particular order of evaluation is broken.
>
>You've just been lucky (or not, depending on the point of view) up to  
>now. It is typical that such bugs are exposed when the optimization  
>level is changed, which is a good reason to test regularly with both - 
>O0 and -O2.

True - the standard doesn't say anything about the order in which parameter
values are passed/pushed on the stack.  (BTW - even ABIs aren't "standards", 
but rather "conventions".)  But it is absolutely necessary to know (and be 
able to explicitly define/control) this order if one is doing inter-language
or cross-tool development; without knowing the stack frame, how can an
assembler routine call a routine developed in 'C' or vice versa?  Most other
compilers I'm familiar with allow a declspec or define their call linkage
(standard, pascal, cdecl, etc.) to specify a particular order at compile-time.
(Obviously, functions defined as such are not candidates for the optimizations
to which you alluded.  But correctness trumps speed - getting invalid behavior
or bad results faster get me nowhere.)  Unfortunately, I looked through the gcc
documentation for something similar about a month ago, and the only thing I 
could find was an option that controls how stack frames are built - but this
was an option used when compiling gcc/g++ itself.

If anyone knows of switches that control the argument order in g++, please let
me know - I'll find the details in the docs (if it's there), but I didn't see 
anything when I looked.

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

* Re: Function Argument Evaluation
  2006-12-06 16:21   ` Young, Michael
@ 2006-12-06 16:43     ` Daniel Llorens del Río
  2006-12-06 17:01       ` Young, Michael
  2006-12-06 16:47     ` Perry Smith
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Daniel Llorens del Río @ 2006-12-06 16:43 UTC (permalink / raw)
  To: gcc-help

	
On 6 Dec, 2006, at 17:21, Young, Michael wrote:

>> I /think/ that with -O0 the arguments are evaluated left to right.
>> However, neither the standards nor gcc make any guarantee about
>> argument evaluation order. Not now and not historically either. Any
>> code that relies on a particular order of evaluation is broken.
>>
>> You've just been lucky (or not, depending on the point of view) up to
>> now. It is typical that such bugs are exposed when the optimization
>> level is changed, which is a good reason to test regularly with  
>> both -
>> O0 and -O2.
>
> True - the standard doesn't say anything about the order in which  
> parameter
> values are passed/pushed on the stack.  (BTW - even ABIs aren't  
> "standards",
> but rather "conventions".)  But it is absolutely necessary to know  
> (and be
> able to explicitly define/control) this order if one is doing inter- 
> language
> or cross-tool development; without knowing the stack frame, how can an
> assembler routine call a routine developed in 'C' or vice versa?

I think you are confusing here two very different things:

1) argument evaluation order: this has nothing to do with the calling  
convention (pascal, cdecl, register). It is unspecified. If you need  
to control it, evaluate the arguements yourself before the function  
call.

2) argument passing order: this is related to the calling convention.  
The compiler certainly guarantees that the arguments are put on the  
stack or loaded into registers in a specified order. gcc has the  
attributes stdcall, cdecl, etc. to control this, like any other  
compiler.

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

* Re: Function Argument Evaluation
  2006-12-06 16:21   ` Young, Michael
  2006-12-06 16:43     ` Daniel Llorens del Río
@ 2006-12-06 16:47     ` Perry Smith
  2006-12-06 16:48     ` John Love-Jensen
  2006-12-06 17:01     ` Andrew Haley
  3 siblings, 0 replies; 9+ messages in thread
From: Perry Smith @ 2006-12-06 16:47 UTC (permalink / raw)
  To: Young, Michael; +Cc: Daniel Llorens del Río, gcc-help

On Dec 6, 2006, at 10:21 AM, Young, Michael wrote:

>>> Good morning,
>>>
>>> Historically it's always been that arguments passed into  
>>> functions get
>>> evaluated from left to right
>>
>> Not true.
>>
>>> Ie. 'int foo(int a, char *b, float c) { }
>>>
>>> But I'm noticing that with gcc-4.1.1 (on Fedora Core 5), that  
>>> does not
>>> seem to be the case.  We have some code, granted it may be  
>>> fragile or
>>> broken code, that relies on the arguments being evaluated from  
>>> left to
>>> right and seems like that's not the case.  In my code the arguments
>>> seem
>>> to be being evaluated right to left.
>>
>> I /think/ that with -O0 the arguments are evaluated left to right.
>> However, neither the standards nor gcc make any guarantee about
>> argument evaluation order. Not now and not historically either. Any
>> code that relies on a particular order of evaluation is broken.
>>
>> You've just been lucky (or not, depending on the point of view) up to
>> now. It is typical that such bugs are exposed when the optimization
>> level is changed, which is a good reason to test regularly with  
>> both -
>> O0 and -O2.
>
> True - the standard doesn't say anything about the order in which  
> parameter
> values are passed/pushed on the stack.  (BTW - even ABIs aren't  
> "standards",
> but rather "conventions".)  But it is absolutely necessary to know  
> (and be
> able to explicitly define/control) this order if one is doing inter- 
> language
> or cross-tool development; without knowing the stack frame, how can an
> assembler routine call a routine developed in 'C' or vice versa?   
> Most other
> compilers I'm familiar with allow a declspec or define their call  
> linkage
> (standard, pascal, cdecl, etc.) to specify a particular order at  
> compile-time.
> (Obviously, functions defined as such are not candidates for the  
> optimizations
> to which you alluded.  But correctness trumps speed - getting  
> invalid behavior
> or bad results faster get me nowhere.)  Unfortunately, I looked  
> through the gcc
> documentation for something similar about a month ago, and the only  
> thing I
> could find was an option that controls how stack frames are built -  
> but this
> was an option used when compiling gcc/g++ itself.
>
> If anyone knows of switches that control the argument order in g++,  
> please let
> me know - I'll find the details in the docs (if it's there), but I  
> didn't see
> anything when I looked.

Are you mixing two concepts?  The "order of evaluation" is not the  
same as the
calling convention.

For example, on AIX the calling convention is to have the first  
parameter in
register 3, the second in register 4.  But they can get evaluated in  
any order (and
they never really get pushed on the stack).

Perry Smith ( pedz@easesoftware.com )
Ease Software, Inc. ( http://www.easesoftware.com )

Low cost SATA Disk Systems for IBMs p5, pSeries, and RS/6000 AIX systems


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

* Re: Function Argument Evaluation
  2006-12-06 16:21   ` Young, Michael
  2006-12-06 16:43     ` Daniel Llorens del Río
  2006-12-06 16:47     ` Perry Smith
@ 2006-12-06 16:48     ` John Love-Jensen
  2006-12-06 17:01     ` Andrew Haley
  3 siblings, 0 replies; 9+ messages in thread
From: John Love-Jensen @ 2006-12-06 16:48 UTC (permalink / raw)
  To: Young, Michael, MSX to GCC

Hi Michael,

Is the issue "order of function argument evaluation", or "order function
arguments are pushed on the stack"?

The former is undefined, as already discussed.

The latter is "defined" by a variety of mutually incompatible calling
conventions, which answer such questions as:
+ how is the function name "mangled" (leading underscore? uppercased? C++
mangled?) 
+ are arguments pushed left to right, or right to left; and perhaps into
registers (e.g., DOS INT calls, or Amiga OS calls)
+ how is the return value returned to the caller
+ who is responsible for cleaning up the stack: the caller or callee

I'm sure that exception handling and stack unwinding and other ABI
considerations plays into the equation too, somehow, but I've just thrown up
my hands and said "It's PFM" and let the compiler GNUrus figure out the
hairy, scary details.

For example, MSVS6 has these:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/ht
ml/_core_argument_passing_and_naming_conventions.asp

GCC 4.1.1 has these (interspersed amongst other function attributes):
http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Function-Attributes.html

HTH,
--Eljay

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

* RE: Function Argument Evaluation
  2006-12-06 16:21   ` Young, Michael
                       ` (2 preceding siblings ...)
  2006-12-06 16:48     ` John Love-Jensen
@ 2006-12-06 17:01     ` Andrew Haley
  3 siblings, 0 replies; 9+ messages in thread
From: Andrew Haley @ 2006-12-06 17:01 UTC (permalink / raw)
  To: Young, Michael; +Cc: Daniel Llorens del Río, gcc-help

Young, Michael writes:
 > >> Good morning,
 > >>
 > >> Historically it's always been that arguments passed into functions get
 > >> evaluated from left to right
 > >
 > >Not true.
 > >
 > >> Ie. 'int foo(int a, char *b, float c) { }
 > >>
 > >> But I'm noticing that with gcc-4.1.1 (on Fedora Core 5), that does not
 > >> seem to be the case.  We have some code, granted it may be fragile or
 > >> broken code, that relies on the arguments being evaluated from left to
 > >> right and seems like that's not the case.  In my code the arguments  
 > >> seem
 > >> to be being evaluated right to left.
 > >
 > >I /think/ that with -O0 the arguments are evaluated left to right.  
 > >However, neither the standards nor gcc make any guarantee about  
 > >argument evaluation order. Not now and not historically either. Any  
 > >code that relies on a particular order of evaluation is broken.
 > >
 > >You've just been lucky (or not, depending on the point of view) up to  
 > >now. It is typical that such bugs are exposed when the optimization  
 > >level is changed, which is a good reason to test regularly with both - 
 > >O0 and -O2.
 > 
 > True - the standard doesn't say anything about the order in which parameter
 > values are passed/pushed on the stack.  (BTW - even ABIs aren't "standards", 
 > but rather "conventions".)  But it is absolutely necessary to know (and be 
 > able to explicitly define/control) this order if one is doing inter-language
 > or cross-tool development; without knowing the stack frame, how can an
 > assembler routine call a routine developed in 'C' or vice versa?  Most other
 > compilers I'm familiar with allow a declspec or define their call linkage
 > (standard, pascal, cdecl, etc.) to specify a particular order at compile-time.
 > (Obviously, functions defined as such are not candidates for the optimizations
 > to which you alluded.  But correctness trumps speed - getting invalid behavior
 > or bad results faster get me nowhere.)  Unfortunately, I looked through the gcc
 > documentation for something similar about a month ago, and the only thing I 
 > could find was an option that controls how stack frames are built - but this
 > was an option used when compiling gcc/g++ itself.
 > 
 > If anyone knows of switches that control the argument order in g++, please let
 > me know - I'll find the details in the docs (if it's there), but I didn't see 
 > anything when I looked.

What do you mean by "argument order" ?  The order of evaluation isn't
specified by anything.  The order in which arguments are pushed onto
the stack depends on the operating system, not on gcc's designe.  We
do whatever the OS needs.

Andrew.

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

* RE: Function Argument Evaluation
  2006-12-06 16:43     ` Daniel Llorens del Río
@ 2006-12-06 17:01       ` Young, Michael
  0 siblings, 0 replies; 9+ messages in thread
From: Young, Michael @ 2006-12-06 17:01 UTC (permalink / raw)
  To: Daniel Llorens del Río, gcc-help

>I think you are confusing here two very different things.

My bad... you're right - I read "evaluation order" and immediately thought of calling convention.  I generally avoid problems involving the former by reorganizing my code to eliminate sequence point / evaluation order dependencies.

I'll look again through the docs for stdcall calling convention, which is what I was looking for previously.
Thanks for the correction.
  - Mike

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

end of thread, other threads:[~2006-12-06 17:01 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-12-06 15:48 Function Argument Evaluation Brian D. McGrew
2006-12-06 15:59 ` John Love-Jensen
2006-12-06 16:00 ` Daniel Llorens del Río
2006-12-06 16:21   ` Young, Michael
2006-12-06 16:43     ` Daniel Llorens del Río
2006-12-06 17:01       ` Young, Michael
2006-12-06 16:47     ` Perry Smith
2006-12-06 16:48     ` John Love-Jensen
2006-12-06 17:01     ` Andrew Haley

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