Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C has no evaluation order of function parameters, am I missing something?

33 views
Skip to first unread message

sili...@gmail.com

unread,
Aug 9, 2019, 12:37:28 PM8/9/19
to
I saw a post with a code exactly the same as this (http://coliru.stacked-crooked.com/a/ac8e130d355d8f1e) one, and it said the output is "12 11" in the post. Now, that is the output I get when I run the code, but I don't see how there can be a specified output when C has no evaluation order of function parameters, am I missing something?

Kenny McCormack

unread,
Aug 9, 2019, 12:54:26 PM8/9/19
to
In article <0fa0ca89-6e91-4f23...@googlegroups.com>,
Please post code here. That's the expected behavior for CLC posters.

We don't like to (in fact, some of us can't) follow arbitrary links.

--
Modern Conservative: Someone who can take time out from demanding more
flag burning laws, more abortion laws, more drug laws, more obscenity
laws, and more police authority to make warrantless arrests to remind
us that we need to "get the government off our backs".

sili...@gmail.com

unread,
Aug 9, 2019, 12:57:06 PM8/9/19
to
On Friday, August 9, 2019 at 7:37:28 PM UTC+3, sili...@gmail.com wrote:
> I saw a post with a code exactly the same as this (http://coliru.stacked-crooked.com/a/ac8e130d355d8f1e) one, and it said the output is "12 11" in the post. Now, that is the output I get when I run the code, but I don't see how there can be a specified output when C has no evaluation order of function parameters, am I missing something?

The code posted directly here:
#include <stdio.h>

int x = 11;

int increment(){
x += 1;
return x;
}

int main(){
printf("%d %d", increment(), x);
return 0;
}
Message has been deleted

James Kuyper

unread,
Aug 9, 2019, 1:24:43 PM8/9/19
to
It's an odd choice to post a question about C to a newsgroup devoted to
C++; comp.lang.c would have been more appropriate. However, except for
one minor detail, this code is valid and has the same behavior in both
languages, and the issue you're talking about applies the same in both.

The detail is that the output from this program does not end in a new
line character. It's implementation-defined whether such a character is
required. Add a \n at the end of the format string and that issue
disappears.

You are correct - the relevant standard for either language explicitly
says that the order of evaluation of the arguments of a function call
is unspecified, so the output of that program is not guaranteed to be
12 11.

Bonita Montero

unread,
Aug 9, 2019, 1:27:09 PM8/9/19
to
Yes, x might be read before or after the call of increment.
But that's not a real problem because no one writes such
brain-damaged code.

James Kuyper

unread,
Aug 9, 2019, 2:22:16 PM8/9/19
to
You'd be surprised - many people learn C after getting preconceptions they acquired when learning other languages. Many people like you pay more attention to the way a particular C compiler works than they do to the actual standard.
For both those reasons, and many others, people often acquire the misconception that the order in which arguments to a function call are evaluated is guaranteed. Once they've done so, it's only natural that sooner or later they will write code that depends upon the expected order.
I've seen people complain in this very newsgroup about a compiler supposedly mishandling code like printf("%d %d\n", x+×, x++), which really isn't possible, because the behavior of such code is undefined (not merely unspecified).

Kenny McCormack

unread,
Aug 9, 2019, 3:35:15 PM8/9/19
to
In article <1b2121ee-8668-4901...@googlegroups.com>,
<sili...@gmail.com> wrote:
...
>I'll just put the code here as well:
>#include <stdio.h>
>
>int x = 11;
>
>int increment(){
> x += 1;
> return x;
>}
>
>int main(){
> printf("%d %d", increment(), x);
> return 0;
>}

Thank you. That helps a lot.

Anyway, the answer to your question is that, yes, the C language, as
defined by the standards documents (that which, leader Keith will tell you,
is the only thing we can discuss in this group), does not specify the order
of evaluation of function args. In fact, I think the above program
qualifies as the dreaded "undefined behavior", and we all know what that
means (*).

That said, the fact is that most Unix implementations of C (and, in fact,
most implementations of C period) use what is called the "cdecl" calling
convention, which means that things are pushed onto the "stack" (oooh!!! I
said the naughty word!!!) in right-to-left order, so that you get the
output you see. The original value of x is pushed first, then the
incremented value. The incremented value is printed first, followed by the
original value.

But, as noted, since it is "undefined behavior", anything could happen,
including spaghetti flying out of your nose. If, however, your
implementation specifies "cdecl", as many/most/all do, then you're safe.

Windows, incidentally, is "cdecl" for non-API functions, but "Pascal" for
WinAPI calls.

(*) In fact, a true pedant would point out that the fact that there is no
trailing newline in the printf() statement also generates "undefined behavior".

--
The last time a Republican cared about you, you were a fetus.

Keith Thompson

unread,
Aug 9, 2019, 5:02:45 PM8/9/19
to
sili...@gmail.com writes:
[...]
> Im not sure how to edit the post, I replied to it with the code, but
> it seems only to be viewable for me, not for other users. So, how do I
> edit the post?

You can't edit a post. Once you post something on Usenet, it's out
there. (There are mechanisms to cancel posts, but for historical
reasons they usually don't work.)

If you want to correct something, post a followup -- which you already
did, and I was able to see it. It can take a little while for a post to
propagate.

[...]

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Tim Rentsch

unread,
Aug 14, 2019, 12:26:15 PM8/14/19
to
r...@zedat.fu-berlin.de (Stefan Ram) writes:

> It has been written:
>
>> Subject: C has no evaluation order of function parameters
>
> main.c
>
> #include <math.h>
> #include <stdio.h>
>
> double f( int const n )
> { printf( "%d\n", n );
> return 0; }
>
> int main( void )
> { pow( f( 0 ), f( 1 )); }
>
> For one example, the above might have undefined behavior,

No, it cannot.

> because
>
> |side effects and value computations of subexpressions are
> |unsequenced
>
> and we cannot know whether >>printf<< has any (internal)
> side-effects on a scalar object.
>
> |If a side effect on a scalar object is unsequenced relative
> |to either a different side effect on the same scalar object
> |or a value computation using the value of the same scalar
> |object, the behavior is undefined.

None of that matters because function calls are (at a minimum)
indeterminately sequenced. The calls 'f(0)' and 'f(1)' cannot
overlap: one must be evaluated completely before the other, even
though we don't know which is done first and which is done second.

Even if function calls were not indeterminately sequenced, in C++
this example still would not have undefined behavior. Take this
simple example (disclaimer: not compiled):

#include <math.h>
#include <stdio.h>

int
main(){
int x = 0;
double d = pow( x, ++x );
printf( "d is %f\n", d );
return 0;
}

In C this program has undefined behavior. In C++ it does not,
because the evaluations of function arguments are indeterminately
sequenced with respect to each other. There is unspecified
behavior, but not undefined behavior.
0 new messages