473,547 Members | 2,653 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Evaluation order of assignment statement

Does the C specification define the order of evaluation of assignment
statements?

For example, what should be the output from the following:

int foo1() { printf("foo1\n" ); return 0; }
int foo2() { printf("foo2\n" ); return 0; }
int foo3() { printf("foo3\n" ); return 0; }

int main()
{
int array[1];
array[foo1()] = foo2() + foo3();
}

I'm asking this question since I'm getting conflicting results on
different compilers, and want to understand whether this is a compiler
bug or not.

gcc prints: foo1, foo2, foo3.
Microsoft Visual C prints: foo2, foo3, foo1.

Thanks.

Oct 23 '06 #1
10 3298
na****@gmail.co m wrote:
Does the C specification define the order of evaluation of assignment
statements?

For example, what should be the output from the following:

int foo1() { printf("foo1\n" ); return 0; }
int foo2() { printf("foo2\n" ); return 0; }
int foo3() { printf("foo3\n" ); return 0; }

int main()
{
int array[1];
array[foo1()] = foo2() + foo3();
It's because the order of execution of the functions foo2(),
foo3() or foo1() is undefined. There's nothing wrong with
the compilers.

There no way to tell which function of the three is gonna
get called first.
}

I'm asking this question since I'm getting conflicting results on
different compilers, and want to understand whether this is a compiler
bug or not.

gcc prints: foo1, foo2, foo3.
Microsoft Visual C prints: foo2, foo3, foo1.
John
--
John Smith
Oct 23 '06 #2
In article <11************ **********@e3g2 000cwe.googlegr oups.com>,
<na****@gmail.c omwrote:
>Does the C specification define the order of evaluation of assignment
statements?
>For example, what should be the output from the following:
>int foo1() { printf("foo1\n" ); return 0; }
int foo2() { printf("foo2\n" ); return 0; }
int foo3() { printf("foo3\n" ); return 0; }
>int main()
{
int array[1];
array[foo1()] = foo2() + foo3();
}
That isn't really a question about the order of evaluation of
assignment statements: it's really a question about the order of
evaluation of the components of an expression.

For the most part, the answer is NO.

The full answer involves complex rules about "sequence points", and
there are continual arguments about what the rules mean in obscure
circumstances. Even seasoned pros don't always agree (at least
for the first dozen flames) about the implications of sequence points
in some unusual expressions.
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Oct 23 '06 #3
na****@gmail.co m wrote:
Does the C specification define the order of evaluation of assignment
statements?
No. The rest follows.

--
Best regards,
Andrey Tarasevich
Oct 23 '06 #4
Thank you all, I just wanted to make sure it really was not defined in
any specification (that's what I originally thought).

This came up since I saw a weird bug, where a function on the RHS of an
assignment had side effects that incremented a variable used as a
subscript index on the LHS...

--
Nachch

Oct 23 '06 #5
In article <11************ **********@e3g2 000cwe.googlegr oups.com>,
<na****@gmail.c omwrote:
>Thank you all, I just wanted to make sure it really was not defined in
any specification (that's what I originally thought).
You should include enough context so that oeople can follow the
discussion without having to try to locate previous postings.

Your question was about the order of evaluation, especially for
assignment statements.

>This came up since I saw a weird bug, where a function on the RHS of an
assignment had side effects that incremented a variable used as a
subscript index on the LHS...
If I recall correctly, that situation is well defined. Each function call
has a sequence point surrounding it -- it is the order of those sequence
points relative to those of other function calls is not defined. But because
there is a sequence point for the function call, any side effects
of the function call are considered to be finalized before evaluation
of the left hand side (if my brain hasn't frotzed this up yet again.)

Of course, well-defined code is not necessarily even close to
"readable and maintainable" code!. I'd want to have very good reasons
before coding anything like that myself!
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
Oct 23 '06 #6
Walter Roberson wrote:
In article <11************ **********@e3g2 000cwe.googlegr oups.com>,
<na****@gmail.c omwrote:
Thank you all, I just wanted to make sure it really was not defined in
any specification (that's what I originally thought).

You should include enough context so that oeople can follow the
discussion without having to try to locate previous postings.

Your question was about the order of evaluation, especially for
assignment statements.

This came up since I saw a weird bug, where a function on the RHS of an
assignment had side effects that incremented a variable used as a
subscript index on the LHS...

If I recall correctly, that situation is well defined. Each function call
has a sequence point surrounding it -- it is the order of those sequence
points relative to those of other function calls is not defined. But because
there is a sequence point for the function call, any side effects
of the function call are considered to be finalized before evaluation
of the left hand side (if my brain hasn't frotzed this up yet again.)

Of course, well-defined code is not necessarily even close to
"readable and maintainable" code!. I'd want to have very good reasons
before coding anything like that myself!
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
[Sorry about the lost context, I'm using the Google client, so I just
see a posting thread]

Anyway, regarding this specific issue: I'm getting different results
with different compilers.
In my original post I used function calls that printed some output
because that was what I used to help me visualize the timeline of
execution.

My problem is actually more like this:

int g_index = 0; // global

int bar() { g_index++; return 17; }

int foo()
{
int array[10];
array[g_index] = bar();
}

Using gcc, I get 17 written in array[0].
Using Microsoft Visual C compiler, I get 17 written in array[1].

So, gcc must have evaluated the LHS first into a memory position, then
evaluated the RHS, and finally made the assignment.
MSVC on the other hand evaluated RHS first.

Is *this* thing defined in the C specification? (*this* as opposed to
the order of function evaluation, which I understand is not defined).

Thank you!
--
Nachch

Oct 23 '06 #7

na****@gmail.co m wrote:
[Sorry about the lost context, I'm using the Google client, so I just
see a posting thread]

Right, but not everyone else is.

Anyway, regarding this specific issue: I'm getting different results
with different compilers.
In my original post I used function calls that printed some output
because that was what I used to help me visualize the timeline of
execution.

My problem is actually more like this:

int g_index = 0; // global

int bar() { g_index++; return 17; }

int foo()
{
int array[10];
array[g_index] = bar();
}

Using gcc, I get 17 written in array[0].
Using Microsoft Visual C compiler, I get 17 written in array[1].

So, gcc must have evaluated the LHS first into a memory position, then
evaluated the RHS, and finally made the assignment.
MSVC on the other hand evaluated RHS first.

Is *this* thing defined in the C specification? (*this* as opposed to
the order of function evaluation, which I understand is not defined).

Short answer: no. There is no sequence point separating the evaluation
of the array subscript expressing and the function call, so there's
no defined order.

In a slightly more complex case, "array[bar2()] = bar();" you could see
either bar or bar2 get called first, but it is guaranteed that the one
that gets called first is fully complete, and all side effects
evaluated, before the second is called (or any of its parameters
evaluated - although there aren't any in this example).

In your example, you probably want to do something like:

t = bar();
array[g_index] = t;

or:

t = g_index;
array[t] = bar();
depending on what you actually want to happen.

Oct 23 '06 #8
In article <11************ **********@m7g2 000cwm.googlegr oups.com>,
<na****@gmail.c omwrote:
>My problem is actually more like this:
>int g_index = 0; // global
>int bar() { g_index++; return 17; }
>int foo()
{
int array[10];
array[g_index] = bar();
}
>Is *this* thing defined in the C specification? (*this* as opposed to
the order of function evaluation, which I understand is not defined).
There are subtle nuances to sequence points that I don't think I
am clear on myself. Puzzling through the C89 wording, I -think- the
above is not valid.

There is a sequence point before the actual call to bar(), which
I understand to mean that g_index would not yet have been computed
(according to the abstract semantics.) However, at -this- level
there is no sequence point between the start of the call to bar and
the end of the assignment. An object may be modified only once
between the previous sequence point and the next, and g_index is
modified only once by the call, so that part itself is okay. However,
the previous value of an object may be accessed only to determine
the value to store, and that's being violated because the
value of g_index has to be accessed inside bar() in order to determine
the new value to store -and- the value of g_index needs to be accessed
in order to determine the subscript to use. So if I understand
correctly, that is two kinds of accesses where only one is
permitted.

But if my understanding is correct, then the following would work,
and I -suspect- it won't:

int g_index = 0; /* global */
int bar() { g_index++; return 17; }
int copyarg( int inval ) { return inval; }
void foo(void) {
int array[10];
array[g_index] = copyarg( bar() );
}

The idea here being that with the extra layer of function call,
there is a sequence point before the call to copyarg() so the
sideeffects of bar() would be finalized before copyarg() was called,
and hence the implication would be that the g_index in the subscript
should get the side-effect'd value of g_index . But it doesn't sound
right that putting in an extra layer of call could make right
a side effect.
--
All is vanity. -- Ecclesiastes
Oct 23 '06 #9
>In article <11************ **********@m7g2 000cwm.googlegr oups.com>,
<na****@gmail.c omwrote:
[with vertical compression by me]
>>int g_index = 0; // global
int bar() { g_index++; return 17; }
int foo() {
int array[10];
array[g_index] = bar();
}
>>Is *this* thing defined in the C specification? (*this* as opposed to
the order of function evaluation, which I understand is not defined).
The precise answer is that it is "unspecifie d".

In article <eh**********@c anopus.cc.umani toba.ca>
Walter Roberson <ro******@ibd.n rc-cnrc.gc.cawrote :
>There are subtle nuances to sequence points that I don't think I
am clear on myself. Puzzling through the C89 wording, I -think- the
above is not valid.
Depends what you mean by "valid".

The sequence points that surround the call to, and return from,
function bar(), guarantee that g_index is 0 before, and 1 after,
the call to bar(). (Assuming of course that it has not been altered
before this.) In addition, we can (I believe) be sure that in the
left-hand sub-expression "array[g_index]", g_index is evaluated
either entirely before, or entirely after, the call to bar(). It
will therefore be either 0 or 1.

Unfortunately, there is nothing that says *which* will occur. This
is not even "implementa tion-defined". If it were, the programmer
could read the documentation that comes with the compiler, and find
out whether array[g_index] will be array[0] or array[1], and know
the answer for that particular compiler (perhaps "that compiler with
specific flags", since there might be a compiler switch to choose
one or the other). But it is "unspecifie d", meaning the compiler
does not even have to tell you how it chooses when to evaluate
g_index (i.e., before or after the call to bar()).

That, in turn, means the compiler can make this choice based on
the phase of the moon, the temperature of the CPU, or any other
hard-to-predict item. You can be sure of "zero or one", but not
which.

The way to force the desired order of evaluation -- whatever that
is -- is to capture g_index with a sequence point that is ordered
with respect to the function-call sequence point. For instance:

i = g_index; /* capture value before the call */
array[i] = bar(); /* index with old value */

or:

i = bar(); /* do the call */
array[g_index] = i; /* index with new value */
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Oct 23 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
2659
by: Bhushit Joshipura | last post by:
This post contains one question and one proposal. A. May I know why order of evaluation of arguments is not specified in C/C++? I asked a question in comp.lang.c++ for the following possibility and because the languages do not specify the order of evaluation, doing so was an error. int B::f ( int i, int j = i + 1 ) { // j defaults to i...
15
2919
by: Jens.Toerring | last post by:
Hi, I have a possibly rather stupid question about the order of evaluation in a statement like this: result = foo( x ) - bar( y ); How can I make 100% sure that foo(x) is evaluated before bar(y), where foo() and bar() can be either functions or macros? I got into problems with this when writing some hardware-related stuff where foo()...
77
4671
by: berns | last post by:
Hi All, A coworker and I have been debating the 'correct' expectation of evaluation for the phrase a = b = c. Two different versions of GCC ended up compiling this as b = c; a = b and the other ended up compiling it as a = c; b = c. (Both with no optimizations enabled). How did we notice you may ask? Well, in our case 'b' was a memory...
10
353
by: int main(void) | last post by:
Hi all, In the following program, #include<stdio.h> int main(void) { int x = 10; int y = 10;
9
3483
by: sturlamolden | last post by:
Python allows the binding behaviour to be defined for descriptors, using the __set__ and __get__ methods. I think it would be a major advantage if this could be generalized to any object, by allowing the assignment operator (=) to be overloaded. One particular use for this would be to implement "lazy evaluation". For example it would allow...
54
3874
by: Rasjid | last post by:
Hello, I have just joined and this is my first post. I have never been able to resolve the issue of order of evaluation in C/C++ and the related issue of precedence of operators, use of parentheses. 1) "The order of evaluation of subexpressions is determined by the precedence and grouping of operators."
0
7510
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7437
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7947
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7463
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6032
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5362
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3473
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1923
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
748
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.