Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > a[i] = x[a[i]]++

Reply
Thread Tools

a[i] = x[a[i]]++

 
 
Chris Torek
Guest
Posts: n/a
 
      01-21-2005
>"BRG" <(E-Mail Removed)> wrote in message
>> In the statement: k = x[ k ]++;

[ ... snippage ]
>> Moreover, there appears to be nothing in the C standard to prevent
>> either of the interpretations:
>> t = k; k = x[t]; x[t]++;


[equivalently: old_val = x[k]++; k = old_val;]

>> or
>> k = x[k]; x[k]++;


In article <bb9Id.1622$(E-Mail Removed). net>
xarax <(E-Mail Removed)> wrote:
>[The first] is the correct implementation.


This may be the one you prefer (and the one I prefer, too!), but
unless the Standard actually *says* that, the Standard does not
*say* that.

I believe the wording in the C standards (both C89 and C99) can
reasonably be interpreted *not* to say that. In other words, the
Standard does not say what I want it to say. Too bad for me (and
you, too). So just write:

old_val = x[k]++;
k = old_val;

when you mean that -- and/or lobby for a future DR or TC and/or a
future C standard to actually *say* that the expression has to mean
what you and I want it to mean.

"If the Standard says that the result depends on the phase of the
moon, the programmer should be prepared to look out the window as
necessary." --me
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.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.
 
Reply With Quote
 
 
 
 
BRG
Guest
Posts: n/a
 
      01-21-2005
Chris Torek wrote:

>>"BRG" <(E-Mail Removed)> wrote in message
>>
>>>In the statement: k = x[ k ]++;

>
> [ ... snippage ]
>
>>>Moreover, there appears to be nothing in the C standard to prevent
>>>either of the interpretations:
>>> t = k; k = x[t]; x[t]++;

>
> [equivalently: old_val = x[k]++; k = old_val;]
>
>>>or
>>> k = x[k]; x[k]++;

>
> In article <bb9Id.1622$(E-Mail Removed). net>
> xarax <(E-Mail Removed)> wrote:
>
>>[The first] is the correct implementation.

>
> This may be the one you prefer (and the one I prefer, too!), but
> unless the Standard actually *says* that, the Standard does not
> *say* that.


I agree. I was hoping to find that the C Standard would make this
interpretation correct but I can't see that it does. It seems to me
that it allows either version and this means that we have to treat the
result of this statement as undefined.

> I believe the wording in the C standards (both C89 and C99) can
> reasonably be interpreted *not* to say that. In other words, the
> Standard does not say what I want it to say. Too bad for me (and
> you, too). So just write:
>
> old_val = x[k]++;
> k = old_val;
>
> when you mean that -- and/or lobby for a future DR or TC and/or a
> future C standard to actually *say* that the expression has to mean
> what you and I want it to mean.


I wonder who we lobby. Maybe there is a Committee member watching this?

Brian Gladman
 
Reply With Quote
 
 
 
 
Friedhelm Usenet Waitzmann
Guest
Posts: n/a
 
      01-21-2005
Old Wolf <(E-Mail Removed)>:

>Going by my formulation of the rule, the read of p
>for (p->next = q) may occur after the write of p
>in (p = q), so the behaviour is undefined.


You mean, the standard permits that the left operand (i.e. the
lvalue) of the assignment p->next = q is evaluated *after* the
evaluation of the result?

From draft ISO/IEC JTC1/SC22/WG14 N794:

6.3.16 Assignment operators

Syntax

[...]

Constraints

[...]

Semantics


[#3] An assignment operator stores a value in the object
designated by the left operand. An assignment expression
has the value of the left operand after the assignment,
but is not an lvalue. [...] The side effect of updating
the stored value of the left operand shall occur between
the previous and the next sequence point.

[#4] The order of evaluation of the operands is
unspecified.

The working group regarded the order of evaluation of the
operands as worth to be mentioned ([#4]) but left open the less
obvious possibility, that the left operand (i.e. the lvalue)
might not be computed until the result has been computed and used
in another assignment?

[#3] permits that the "side effect of updating the stored value"
may occur late, but it does not say anything about the time, when the
lvalue itself is computed.

Any comments?
 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      01-22-2005
In article <(E-Mail Removed)>,
Chris Torek <(E-Mail Removed)> wrote:

>"If the Standard says that the result depends on the phase of the
>moon, the programmer should be prepared to look out the window as
>necessary." --me


This would make phase-of-the-moon programs either trivial or
fiendishly complicated.

-- Richard
 
Reply With Quote
 
Friedhelm Usenet Waitzmann
Guest
Posts: n/a
 
      01-22-2005
Andrey Tarasevich <(E-Mail Removed)>:
>Albert van der Horst wrote:
>> Now the above is using the side effect,
>> to mix up in one statement
>> new = x[ old ];
>> x[ old ] += 1;
>>
>> It is *not* equivalent to
>> a[i] = x[ a[i] ] += 1;
>> because, being a post-increment, the original value of
>> x[ a[i] ] must be used.


>This is completely irrelevant. If you read this thread
>carefully, you'll see that the real question is which value of
>'a[i]' is used (old or new), not which value of 'x[a[i]]' is
>used. The latter is pretty much irrelevant.


>The issue with 'a[i]' is present in your version of the
>expression just like it is present in the original version. You
>haven't changed anything important by replacing post-increment
>with compound assignment.


I think, he has: If you replace x[ a[i] ]++ with
(x[ a[i] ] += 1), the following rule regarding the += applies:

From ISO/IEC JTC1/SC22/WG14 N794:

6.3.16.2 Compound assignment

[...]

Semantics

[#3] A compound assignment of the form E1 op= E2
differs from the simple assignment expression
E1 = E1 op (E2) only in that the lvalue E1 is evaluated
only once.

Therefore, in a[i] = (x[ a[i] ] += 1) the prior value of a[i] is
accessed only once before the new value is stored in a[i],
because 6.3.16.2[#3] garanties that x[a[i]] is not evaluated a
second time. Or I am wrong?
 
Reply With Quote
 
Peter Nilsson
Guest
Posts: n/a
 
      01-22-2005
Albert van der Horst wrote:
> Peter Nilsson <(E-Mail Removed)> wrote:
> > Albert van der Horst wrote:
> > > BRG <(E-Mail Removed)> wrote:
> > > > Does anyone here know whether the assignment:
> > > >
> > > > a[i] = x[ a[i] ]++;
> > >
> > > I never use a statement like
> > > x++;
> > > on its own.

> >
> > Why?!
> >
> > > I always do the equivalent (barring the result value)
> > > x += 1;
> > > This shows that it is an assignment, rather than a side effect.

> >
> > Rather poor reasoning since x++ is idiomatic, and because _all_
> > statements are _only_ evaluated for their side effects,
> > assignments or otherwise (e.g. function calls.)

>
> You use side-effect in a politically correct way here.


It's a term defined in the standard...

"Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all _side effects_, ..."

> I thought the context made clear that is not what I say.
> In an expression like (i + j++)
> two thing are happening with j, getting its value and the
> incrementation which I call a side-effect. (And the use is
> not improper, because it is indeed a lasting effect.).


I (think) I understand that. I was pointing out that C turned
assignments and function calls into expression operators. [It's
not the only language to do this, but the consequences do
surprise many people who program other languages.]

> > > (The result of x++ is of course x, then it is thrown away,
> > > oh and by the way, I have incremented x for you.
> > > Extremely silly.)

> >
> > Yes, ": @++ dup @ dup 1+ over ! ;" _is_ silly, but only because
> > Forth is silly.

>
> This leaves a pointer to x and has its value incremented.


Drat! I meant ": @++ dup @ dup 1+ rot ! ;"

> It could be simplified to: @++ 1 over +! ;


I was hoping you would simplify it, although I didn't anticipate
getting my version wrong. ;( But I'm pretty sure what I was
aiming for could be simplified to... : @++ 1 over +! @ ;

Anyway, my point is that, to a Forth programmer, the optimisation
seems obvious. Within C, the same 'obviousness' surrounds the
optimisation of x += 1 to x++; or ++x;.

> It is not equivalent to the c-code x += 1;


It was meant to be equivalent to x++;, i.e. (adr -- n) where
adr is the lvalue (address) of x.

> Lets discuss @+ which leaves an incremented address
> and a content, the equivalent of *p++ in c.
>
> In the context of Forth it is indeed silly to
> do
> @+ DROP
> instead of just
> @
> This is analogous.


In C it depends on the context: *p++; is silly, however
c = *p++; or f(*p++); isn't.

> In the first example you calculate
> two results, then throw one away. Instead of just calculating
> a result.
>
> But more on topic.
> Is my
> x += 1;
> sufficiently un-idiomatic to get some eyes browsed?


As Keith points out, there are subjective cases where it's valid,
but in general it will raise eyebrows.

It will make the reader think that you're entirely clued up
in C, just as my posted attempt at Forth was obviously naive
from a Forth perspective.

> What about
> p += sizeof(struct x);


[Again See Keith's comment, but also....]

Note that sizeof(struct x) cannot generally be expected to be 1.
There is no unary auto-increment-by-something-other-than-1
operator in C. So, p += 2; is not un-idiomatic.

--
Peter

 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      01-23-2005
Richard Bos wrote:
>
> Christian Kandeler <(E-Mail Removed)_invalid> wrote:
>
> > Old Wolf wrote:
> >
> > > the standard is quite clear that in (a = b = 3.1),
> > > a gets the value 3.1 even if b were an int.

> >
> > Really? You should tell that to the gcc people, then:

>
> Or to the C Standard committee:
>
> # The type of an assignment expression is the type of the left operand
> # unless the left operand has qualified type, in which case it is the
> # unqualified version of the type of the left operand.
> (From 6.5.16#3. Identical wording in C89.)


What happens is:
a gets (double)(int)3.1
b gets (int)3.1
and the assignments are made in no particular order.

--
pete
 
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