Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is a[i] = i++ correct?

Reply
Thread Tools

Is a[i] = i++ correct?

 
 
jeniffer
Guest
Posts: n/a
 
      12-27-2007
Hi

I want to know why is a[i] = i++ ; wrong? People say that it is
because of different parsing during compilation.Please explain
technically why it is wrong/behaviour undefined?

Regards,
Jeniffer
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      12-27-2007
jeniffer <(E-Mail Removed)> writes:
> I want to know why is a[i] = i++ ; wrong? People say that it is
> because of different parsing during compilation.Please explain
> technically why it is wrong/behaviour undefined?


This is question 3.1 in the comp.lang.c FAQ, <http://www.c-faq.com>.
A number of other questions in section 3 address this point.

It's not a matter of "different parsing"; there's no syntactic
ambiguity. The ambiguity is semantic.

n1256 6.5p2 says:

Between the previous and next sequence points an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be read only to
determine the value to be stored.

The use of the word "shall" outside a constraint means that any
violation invokes undefined behavior. In ``a[i] = i++;'' the value of
i is read (that's ok) and modified (ok), and the previous value is
read to determine the value to be stored in i (ok) -- but the value is
*also* read to determine which element of the array to modify
(kaboom!).

Even without the above rule, the standard doesn't specify the order of
evaluation; the determination of which array element to modify could
occur either before or after i is incremented. If that were the only
issue, then if i==2 before the statement is executed, it could modify
either a[2] or a[3]. But 6.5p2 says that (more or less) that whenever
such an ambiguity occurs, the results aren't limited to differing
orders of evaluation; *anything* can happen. The point of all this is
to allow for more aggressive optimization; if the compiler doesn't
need to worry about consistent results for ambiguous expressions, it
can generate better code for unambiguous expressions.

--
Keith Thompson (The_Other_Keith) <(E-Mail Removed)>
[...]
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      12-27-2007
jeniffer said:

> Hi
>
> I want to know why is a[i] = i++ ; wrong?


What do you think it should mean? Given this code:

int a[3] = { 5, 7, 9 };
i = 0;
a[i] = i++; /* bug */

which member of a[] do you think will be updated, and to what value?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Kaz Kylheku
Guest
Posts: n/a
 
      12-27-2007
On Dec 27, 3:45*am, jeniffer <(E-Mail Removed)> wrote:
> Hi
>
> I want to know why is *a[i] = i++ ; wrong? People say that it is
> because of different parsing during compilation.Please explain
> technically why it is wrong/behaviour undefined?


This has been covered in a thousand and one previous discussion
threads in this newsgroup. It has coverage in the FAQ also.

Or you could just search the newsgroup archives for the one thousand
and one threads that have re-hashed this problem over and over again.

I just typed this exact query into Google:

comp.lang.c FAQ "a[i] = i++"

At the time of writing, the first hit points to a copy of the FAQ, and
highlights the section for you where "a[i] = i++" is discussed.

Visit:

http://c-faq.com/expr/index.html
http://c-faq.com/expr/evalorder4.html

If that's not enough, you can easily obtain a draft copy of the ISO
standard for the programming language and look up the exact rules. The
quickest way is to google by document number. Use:

ISO 9899:1999

and click "I'm feeling lucky" to get to a PDF. Look at section 6.5
Expressions, second paragraph.
 
Reply With Quote
 
Chris Dollin
Guest
Posts: n/a
 
      12-28-2007
jeniffer wrote:

> I want to know why is a[i] = i++ ; wrong? People say that it is
> because of different parsing during compilation.Please explain
> technically why it is wrong/behaviour undefined?


Even supposing it were not specifically undefined (ie, the C
Standard says that it doesn't care what this code does), what
would you expect it to /mean/?

The evaluation order of the address of `a[i]` and `i++` is
implementation-specific, and the timing of the increment to `i`
is implementation-specific. The rule the implementation uses
to order these things can be arbitrarily obscure. So, even
if it means something specific on your implementation, today,
when there's left-over Christmas pudding in the fridge and
you can't face another turkey sandwich, it needn't mean the
same thing tomorrow; which is not a good recipe for portable
code.

Let's not mention that the intention of the writer of that
code is completely unclear.

--
Another POV Hedgehog
Scoring, bah. If I want scoring I'll go play /Age of Steam/.

 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      12-28-2007
In article <rd1dj.112184$(E-Mail Removed)> ,
Chris Dollin <(E-Mail Removed)> wrote:
>jeniffer wrote:
>
>> I want to know why is a[i] = i++ ; wrong? People say that it is
>> because of different parsing during compilation.Please explain
>> technically why it is wrong/behaviour undefined?

>
>Even supposing it were not specifically undefined (ie, the C
>Standard says that it doesn't care what this code does), what
>would you expect it to /mean/?


Get off the "the C standard says..." horse and think logically, like a
human being for a second, and it becomes clear. When a human sees the
above, they logically think:
1) Evaluate the RHS
2) Assign it to the LHS
in that order. So, obviously, if i=0 on start, then at end, a[1] will
have been assigned the value 0[*]. Though C doesn't always get this right
(of course, since the C standard allows it, there's no crime here),
C-like scripting languages (e.g., AWK) do, IME, get it right.
[*] Whether or not doing this makes any sense is, of course, not for us
to say.

>Let's not mention that the intention of the writer of that
>code is completely unclear.


Wrong. See above.

 
Reply With Quote
 
Richard Harter
Guest
Posts: n/a
 
      12-28-2007
On Thu, 27 Dec 2007 12:13:10 +0000, Richard Heathfield
<(E-Mail Removed)> wrote:

>jeniffer said:
>
>> Hi
>>
>> I want to know why is a[i] = i++ ; wrong?

>
>What do you think it should mean? Given this code:
>
>int a[3] = { 5, 7, 9 };
>i = 0;
>a[i] = i++; /* bug */
>
>which member of a[] do you think will be updated, and to what value?


If C used a left to right order of application similar to that
for arithmetic (with the as-if rule as a back door) then the
results would be well defined. After the statement a[0] would be
0 and i would be 1. Similarly, the statements

i=0;
a[i++] = ++i + i++;

would evaluate as follows:

The target of the assignment is a[0].
i is incremented after computing the location to become 1.
On the RHS i is incremented to become 2. (++i)
i is added to i to produce 4; once the addition is completed i is
incremented to become 3. (i++).

Of course C does not guarantee the order of evaluation except in
special cases, and it is important to understand that it does
not. One can argue that not guaranteeing the preservation of
code order is a design flaw in the C language, but it doesn't
matter - C is cast in stone.




 
Reply With Quote
 
christian.bau
Guest
Posts: n/a
 
      12-28-2007
On Dec 28, 3:34*pm, (E-Mail Removed) (Kenny McCormack)
wrote:

> Get off the "the C standard says..." horse and think logically, like a
> human being for a second, and it becomes clear. *When a human sees the
> above, they logically think:
> * * * * 1) Evaluate the RHS
> * * * * 2) Assign it to the LHS
> in that order. *So, obviously, if i=0 on start, then at end, a[1] will
> have been assigned the value 0[*]. *Though C doesn't always get this right
> (of course, since the C standard allows it, there's no crime here),
> C-like scripting languages (e.g., AWK) do, IME, get it right.


Java programmers all over the world think you are completely wrong. In
Java, a [i] = i++; has defined behaviour. The expression is evaluated
from left to right. So first it evaluates the lvalue a [i], then the
right hand side i++. The array element changed is determined by the
original value of i.

On the other hand, nobody cares about expressions like this. What
programmers and compiler writers care about are expressions that most
likely don't do this kind of thing, but possibly might, like a [i] =
(*p)++; . A C compiler can evaluate the address of a [i] and the value
of (*p)++ in any order it likes, without having to care about the
perverted case that p == &i. If evaluating the left side first is
faster, the compiler can evaluate the left hand side first. If
evaluating the right hand side first is faster, it does that the right
hand first.
 
Reply With Quote
 
Rick
Guest
Posts: n/a
 
      12-28-2007
On Thu, 27 Dec 2007 03:45:29 -0800 (PST), jeniffer
<(E-Mail Removed)> wrote:

>I want to know why is a[i] = i++ ; wrong? People say that it is
>because of different parsing during compilation.Please explain
>technically why it is wrong/behaviour undefined?


Good afternoon, Jeniffer.

Looks like I'm the only one here who's going to give you a straight
answer without chastising you first for not reading the FAQ.

The answer is that C does not guarantee order of evaluation.
Therefore, i++ might be evaluated first, before being applied as an
index into a[], or it might be evaluated last, and the compiler is
perfectly free to do it either way.

So, if i started off as, say, 2, then a[i] might be a[2], or it might
be a[3].

Hope this helps...
 
Reply With Quote
 
Kenny McCormack
Guest
Posts: n/a
 
      12-28-2007
In article <(E-Mail Removed)>,
christian.bau <(E-Mail Removed)> wrote:
>On Dec 28, 3:34*pm, (E-Mail Removed) (Kenny McCormack)
>wrote:
>
>> Get off the "the C standard says..." horse and think logically, like a
>> human being for a second, and it becomes clear. *When a human sees the
>> above, they logically think:
>> * * * * 1) Evaluate the RHS
>> * * * * 2) Assign it to the LHS
>> in that order. *So, obviously, if i=0 on start, then at end, a[1] will
>> have been assigned the value 0[*]. *Though C doesn't always get this right
>> (of course, since the C standard allows it, there's no crime here),
>> C-like scripting languages (e.g., AWK) do, IME, get it right.

>
>Java programmers all over the world think you are completely wrong. In
>Java, a [i] = i++; has defined behaviour. The expression is evaluated
>from left to right. So first it evaluates the lvalue a [i], then the
>right hand side i++. The array element changed is determined by the
>original value of i.


Well, that doesn't actually prove anything. What it means is that Java
defined it that way (probably because it was easier to implement) and
the programmers accepted it. It doesn't mean it is desirable (nor, of
course, does it mean it is undesirable).

>On the other hand, nobody cares about expressions like this.


Agreed.

 
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




Advertisments