Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Order of function parameters evaluation

Reply
Thread Tools

Order of function parameters evaluation

 
 
subnet
Guest
Posts: n/a
 
      03-07-2005
What does the standard say about this:

#include <stdio.h>
void somefunc(int a, int b, int c)
{
printf("%d %d %d\n", a, b, c);
}

int main(void) {
int i = 5;
somefunc(i++, i++, i++);
return 0;
}

Compiling with gcc -Wall it gives:

prog.c: In function `main':
prog.c:10: warning: operation on `i' may be undefined
prog.c:10: warning: operation on `i' may be undefined

but it prints 7 6 5 anyway.

Are the function arguments guaranteed to be evaluated right-to-left or
this is not specified by the standard (and the above code produces
UB)?

Thanks
 
Reply With Quote
 
 
 
 
Al Bowers
Guest
Posts: n/a
 
      03-07-2005


subnet wrote:
> What does the standard say about this:
>
> #include <stdio.h>
> void somefunc(int a, int b, int c)
> {
> printf("%d %d %d\n", a, b, c);
> }
>
> int main(void) {
> int i = 5;
> somefunc(i++, i++, i++);
> return 0;
> }
>
> Compiling with gcc -Wall it gives:
>
> prog.c: In function `main':
> prog.c:10: warning: operation on `i' may be undefined
> prog.c:10: warning: operation on `i' may be undefined
>
> but it prints 7 6 5 anyway.
>
> Are the function arguments guaranteed to be evaluated right-to-left or
> this is not specified by the standard (and the above code produces
> UB)?
>


Reading the faq will be helpful.
Its located at:
http://www.eskimo.com/~scs/C-faq/top.html

Start with question 3.2 at
http://www.eskimo.com/~scs/C-faq/q3.2.html

--
Al Bowers
Tampa, Fl USA
mailto: http://www.velocityreviews.com/forums/(E-Mail Removed) (remove the x to send email)
http://www.geocities.com/abowers822/

 
Reply With Quote
 
 
 
 
Peter Nilsson
Guest
Posts: n/a
 
      03-07-2005
subnet wrote:
> What does the standard say about this:
>
> #include <stdio.h>
> void somefunc(int a, int b, int c)
> {
> printf("%d %d %d\n", a, b, c);
> }
>
> int main(void) {
> int i = 5;
> somefunc(i++, i++, i++);
> return 0;
> }


It says the same thing as the last time someone asked this question.


The order of evaluation of function arguments is unspecified.
Since the code modifies a variable more than once without a
(guaranteed) intervening sequence point, the behaviour is
undefined.

> Compiling with gcc -Wall it gives:
>
> prog.c: In function `main':
> prog.c:10: warning: operation on `i' may be undefined
> prog.c:10: warning: operation on `i' may be undefined
>
> but it prints 7 6 5 anyway.


Undefined behaviour lets an implementation do just about
anything, including executing the code and producing output
which seems valid.

> Are the function arguments guaranteed to be evaluated right
> -to-left or this is not specified by the standard (and the
> above code produces UB)?


It is specified as being 'unspecified'. This means that an
implementation is free to choose any arbitrary ordering it
likes, including middle-to-out (whatever that might mean,)
or whatever-looks-easiest-to-compute-first.

--
Peter

 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      03-07-2005
(E-Mail Removed) (subnet) wrote:

> What does the standard say about this:
> somefunc(i++, i++, i++);


That it invokes undefined behaviour.

> Compiling with gcc -Wall it gives:
>
> prog.c: In function `main':
> prog.c:10: warning: operation on `i' may be undefined


Which is correct.

> but it prints 7 6 5 anyway.


Undefined behaviour is allowed to do anything, including what you
thought it should do, but also, more insidiously, doing so on your
machine and crashing on your supervisor's (next-generation) computer.

> Are the function arguments guaranteed to be evaluated right-to-left or
> this is not specified by the standard (and the above code produces
> UB)?


The code produces undefined behaviour, but not (just) because the order
of evaluation is unspecified. It _is_ unspecified, but if that were all
you merely wouldn't know in what order it would print 5, 6 and 7.
However, that's not all. You modify i three times without an intervening
sequence point. This means that you invoke full-blown undefined
behaviour, and the program is allowed to do literally anything within
its powers, ranging from nothing to appearing to work to getting deeply
confused and printing "Wibble!". Or worse. So don't do it.

Richard
 
Reply With Quote
 
subnet
Guest
Posts: n/a
 
      03-07-2005
Al Bowers <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...

> Reading the faq will be helpful.
>[snip]
> Start with question 3.2 at
> http://www.eskimo.com/~scs/C-faq/q3.2.html


Yes, in fact I had already read the FAQ, and I'm aware of sequence
points. The bit I was missing (and that the FAQ say nothing about) was
that the the comma operator, *when used in a list of arguments for a
function* does NOT introduce a sequence point, while it DOES introduce
a sequence point when used in other circumstances (as written in FAQ
3.8, which does not differentiate though).
At least, this is my understanding after some google search on clc
previous posts about the argument (<(E-Mail Removed)>),
but please correct me if I'm wrong.

Thanks
 
Reply With Quote
 
Old Wolf
Guest
Posts: n/a
 
      03-07-2005
subnet wrote:
> Al Bowers <(E-Mail Removed)> wrote in message

news:<(E-Mail Removed)>...
>
> > Reading the faq will be helpful.
> >[snip]
> > Start with question 3.2 at
> > http://www.eskimo.com/~scs/C-faq/q3.2.html

>
> Yes, in fact I had already read the FAQ, and I'm aware of sequence
> points. The bit I was missing (and that the FAQ say nothing about)

was
> that the the comma operator, *when used in a list of arguments for a
> function* does NOT introduce a sequence point, while it DOES

introduce
> a sequence point when used in other circumstances (as written in FAQ
> 3.8, which does not differentiate though).


If you read the language grammar, you will see that a comma
used to separate function arguments is not actually an operator.

"The comma operator" refers to the comma that separates
expressions as part of a larger expression.

An operator has one or more arguments, and a result. That
cannot be said of the comma that separates function arguments.
(Same goes for the comma that separates list items in a
declaration).

 
Reply With Quote
 
Ben Pfaff
Guest
Posts: n/a
 
      03-07-2005
(E-Mail Removed) (subnet) writes:

> Yes, in fact I had already read the FAQ, and I'm aware of sequence
> points. The bit I was missing (and that the FAQ say nothing about) was
> that the the comma operator, *when used in a list of arguments for a
> function* does NOT introduce a sequence point, while it DOES introduce
> a sequence point when used in other circumstances (as written in FAQ
> 3.8, which does not differentiate though).


A comma, used in the most common way in a function call, is not a
comma operator:
f(a, b, c); /* No comma operators. */

You *can* use a comma operator in a function call, but
parentheses or another kind of grouping is needed:
g(a, (b, c), d[e, f]); /* Two uses of comma operator. */

In the former case the commas are not sequence points. In the
latter case, the two instances of a comma operator are sequence
points.

Make sense?
--
"...deficient support can be a virtue.
It keeps the amateurs off."
--Bjarne Stroustrup
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      03-07-2005
subnet wrote:
> Al Bowers <(E-Mail Removed)> wrote...
> > Reading the faq will be helpful.
> >[snip]
> > Start with question 3.2 at
> > http://www.eskimo.com/~scs/C-faq/q3.2.html

>
> Yes, in fact I had already read the FAQ, and I'm aware of sequence
> points. The bit I was missing (and that the FAQ say nothing about)
> was that the the comma operator, *when used in a list of arguments
> for a function* does NOT introduce a sequence point,


That's because the comma token used to separate function arguments is
_not_ a comma operator, but purely a syntactic delimiter.

Consider ( and ). They have different interpretations depending on
whether they are used in function declarators, primary expressions,
or in postfix expressions (function calls.)

It's all layed down in the C grammar.

--
Peter

 
Reply With Quote
 
DHOLLINGSWORTH2
Guest
Posts: n/a
 
      03-08-2005
Try changing the calling convention to pascal.

Then running it again.


"subnet" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> What does the standard say about this:
>
> #include <stdio.h>
> void somefunc(int a, int b, int c)
> {
> printf("%d %d %d\n", a, b, c);
> }
>
> int main(void) {
> int i = 5;
> somefunc(i++, i++, i++);
> return 0;
> }
>
> Compiling with gcc -Wall it gives:
>
> prog.c: In function `main':
> prog.c:10: warning: operation on `i' may be undefined
> prog.c:10: warning: operation on `i' may be undefined
>
> but it prints 7 6 5 anyway.
>
> Are the function arguments guaranteed to be evaluated right-to-left or
> this is not specified by the standard (and the above code produces
> UB)?
>
> Thanks



 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-08-2005
"DHOLLINGSWORTH2" <(E-Mail Removed)> writes:
> "subnet" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
>> What does the standard say about this:
>>
>> #include <stdio.h>
>> void somefunc(int a, int b, int c)
>> {
>> printf("%d %d %d\n", a, b, c);
>> }
>>
>> int main(void) {
>> int i = 5;
>> somefunc(i++, i++, i++);
>> return 0;
>> }
>>
>> Compiling with gcc -Wall it gives:
>>
>> prog.c: In function `main':
>> prog.c:10: warning: operation on `i' may be undefined
>> prog.c:10: warning: operation on `i' may be undefined
>>
>> but it prints 7 6 5 anyway.
>>
>> Are the function arguments guaranteed to be evaluated right-to-left or
>> this is not specified by the standard (and the above code produces
>> UB)?

>
> Try changing the calling convention to pascal.
>
> Then running it again.


[top-posting corrected]

The standard doesn't talk about a "calling convention" called
"pascal", and any method for specifying such a thing is non-standard.

Certainly a compiler can implement an extension that causes something
that invokes undefined behavior to behave in a specified way. It can
even define the behavior for some construct without implementing an
extension (for example, its documentation might guarantee that
function arguments are evaluated left-to-right -- encouraging users to
write non-portable code).

But the OP was specifically asking what the standard says.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Evaluation order of initializer list parameters Juha Nieminen C++ 2 11-19-2011 03:03 AM
Order of evaluation of function arguments dragoncoder C Programming 21 12-23-2005 07:08 PM
Evaluation order of function parameters haroon C Programming 25 12-05-2005 05:22 AM
Order of function evaluation Jens.Toerring@physik.fu-berlin.de C Programming 15 10-27-2003 07:45 PM
Evaluation order for nested function calls cheeser C++ 3 10-05-2003 08:10 AM



Advertisments