Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > what is the right value about a = a++;

Reply
Thread Tools

what is the right value about a = a++;

 
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-07-2012
On 07-Feb-12 05:07, Nick Keighley wrote:
> On Feb 6, 10:35 am, Slash QB <(E-Mail Removed)> wrote:
>>> b = a = a++;
>>> printf("%d, %d\n", a, b);

>>
>> a=a++ or a=++a
>> The above statement when compiled results different in different
>> compilers.
>> So, such expressions are undefined.

>
> isn't that the other way round
>
> the statement is undefined
> =>
> compilers are permitted to produce different answers
> (or trap or crash or anything else weird the compiler writer feels
> like)


Compilers existed prior to the standard, so their divergent behavior
could not possibly be blamed on a non-existent standard allowing it.

AIUI, the job of the ANSI committee was to document the language as it
existed, warts and all, rather than to create a new and perfect language
from scratch. They did overstep that boundary on occasion, eg.
prototypes and (void *), but did so in ways that didn't break any
existing code.

As it turned out, different compilers treated "a=a++;" differently, and
the committee (rightly, IMHO) decided to allow them to continue with
that rather than break existing code that depended on a particular
compiler's ex post facto outlawed behavior.

While I've never taken an exhaustive inventory, I suspect most undefined
behavior in the standard could be traced to such a scenario.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-07-2012
On 07-Feb-12 11:21, Kaz Kylheku wrote:
> On 2012-02-07, James Kuyper <(E-Mail Removed)> wrote:
>> I can think of two plausible defined
>> behaviors for a=a++. One is equivalent to a++, so why bother with the
>> "a="? The other is equivalent to a = a, so why bother writing anything
>> at all?

>
> One particular choice of behavior stands out: the simple, recursive rule:
>
> - evaluate each subexpression completely, includiing all of its side effects,
> before evaluating the parent expression.
>
> - if an expression has several subexpressions, evaluate them left to right.


Nice of you to dictate that people using systems that more efficiently
evaluate sub-expressions from right to left should suffer performance
degradation of all code, even in the majority of cases where the code is
well-written and therefore the order doesn't actually matter, simply
because it doesn't suit your sensibilities.

If you /need/ to know that "foo(bar(), baz());" calls bar() before
baz(), then just write "tmp=bar(); foo(tmp, baz());". There is no need
to suffer that performance penalty, though, in the vast majority of
cases where it _doesn't_ matter.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      02-07-2012
On 02/07/2012 04:19 PM, Stephen Sprunk wrote:
> On 07-Feb-12 05:07, Nick Keighley wrote:
>> On Feb 6, 10:35 am, Slash QB <(E-Mail Removed)> wrote:
>>>> b = a = a++;
>>>> printf("%d, %d\n", a, b);
>>>
>>> a=a++ or a=++a
>>> The above statement when compiled results different in different
>>> compilers.
>>> So, such expressions are undefined.

>>
>> isn't that the other way round
>>
>> the statement is undefined
>> =>
>> compilers are permitted to produce different answers
>> (or trap or crash or anything else weird the compiler writer feels
>> like)

>
> Compilers existed prior to the standard, so their divergent behavior
> could not possibly be blamed on a non-existent standard allowing it.


True; but the fact that different current compilers give different
results cannot be used to validly infer that the behavior is undefined.
The behavior could be implementation-defined, or simply unspecified, or
one of the compilers you're comparing could be non-conforming.

> AIUI, the job of the ANSI committee was to document the language as it
> existed, warts and all, rather than to create a new and perfect language
> from scratch.


It was neither of those things, and both. The committee was tasked with
creating a language specification which was supposed to honor many
different competing principles; some of the hardest work the committee
had to do was balancing those different principles. Some of those
principles, if taken in isolation, could have been interpreted as
calling for a "perfect" language. Other principles called for retaining
compatibility with existing practice.

Incidentally, it was made explicitly clear that "existing code is
important; existing implementations are not". I would presume that was
based upon the fact that, for any reasonably successful implementation
of C, the amount of code written for use on that implementation greatly
outweighed the amount of code required to implement it.

That principle became less important when existing practice was in
conflict with itself. The committee could have specified one particular
choice of behavior, rendering all implementations that didn't make that
choice non-conforming. They could have left the behavior unspecified,
with the range of permitted options wide enough to cover the variety of
existing practice. They could have declared that the behavior was
implementation-defined, requiring a conforming implementation to
document what behavior it chose. Or they could have declared the
behavior undefined, which by definition is compatible with anything that
any compiler might choose to do with the code. The committee did all
four of those things, in different contexts.
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-07-2012
On 07-Feb-12 15:50, Richard Harter wrote:
> On Tue, 07 Feb 2012 15:12:53 -0500, Kenneth Brody
> <(E-Mail Removed)> wrote:
>> On 2/7/2012 3:15 AM, Kaz Kylheku wrote:
>>> I don't want diagnostics; I want strict left to right evaluation order
>>> of operands and subexpressions that complete their side effects before
>>> yielding a value.

>>
>> So, what you are really saying, is you want to eliminate most of C's
>> optimization abilities, by restricting the order in which the expression
>> *must* be evaluated, and side effects *must* be completed?

>
> Well, no, he isn't saying any such thing. You just made it up. The
> fact that evaluation order in C is left to the compilers has very
> little to do with optimization; it is a historical artifact that came
> from endorsing existing practice when the ANSI standard was put
> together. Existing practice then was that compiler writers could do
> evaluations in whatever they pleased and they did.


No, they did evaluations in the order that made the most sense (i.e. had
the best performance) for their particular implementation--and
implementations vary.

For instance, varargs is more straightforward to implement with
right-to-left evaluation of arguments, at least with a stack-based
calling convention. Order of evaluation may not matter for
register-based calling conventions, but if an implementation uses both,
it makes sense to use the same order.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Joel C. Salomon
Guest
Posts: n/a
 
      02-08-2012
On 02/06/2012 05:33 AM, lujnan wrote:
> maybe it shows the c world is not perfect. in this point i like the
> define of java.


If you want Java, you know where to find it.

--Joel
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-08-2012
On 07-Feb-12 22:49, Robert Wessel wrote:
> On Tue, 07 Feb 2012 16:51:17 -0600, Stephen Sprunk
> <(E-Mail Removed)> wrote:
>> On 07-Feb-12 15:50, Richard Harter wrote:
>>> Well, no, he isn't saying any such thing. You just made it up. The
>>> fact that evaluation order in C is left to the compilers has very
>>> little to do with optimization; it is a historical artifact that came
>>> from endorsing existing practice when the ANSI standard was put
>>> together. Existing practice then was that compiler writers could do
>>> evaluations in whatever they pleased and they did.

>>
>> No, they did evaluations in the order that made the most sense (i.e. had
>> the best performance) for their particular implementation--and
>> implementations vary.
>>
>> For instance, varargs is more straightforward to implement with
>> right-to-left evaluation of arguments, at least with a stack-based
>> calling convention. Order of evaluation may not matter for
>> register-based calling conventions, but if an implementation uses both,
>> it makes sense to use the same order.

>
> Depends on which way your stack grows - with downward growth it's
> usually easiest to evaluate varargs right-to-left, but for an upwards
> growing stack left-to-right is usually easier.


How would stack growth direction matter? What matters for varargs is
that the first argument is on the top of the stack, regardless of which
way it grows. If you push the arguments from right to left, the first
argument ends up on top. You _could_ evaluate the arguments from left
to right, store them in registers or elsewhere in memory, and then push
from right to left, but why go through that extra effort?

(This, of course, assumes a stack-based calling convention for varargs
calls, as all of the ABIs I'm familiar with dictate, and possibly for
other calls.)

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      02-08-2012
On 08-Feb-12 08:47, Richard Harter wrote:
> On Tue, 07 Feb 2012 16:51:17 -0600, Stephen Sprunk
> <(E-Mail Removed)> wrote:
>
>> On 07-Feb-12 15:50, Richard Harter wrote:
>>> On Tue, 07 Feb 2012 15:12:53 -0500, Kenneth Brody
>>> <(E-Mail Removed)> wrote:
>>>> On 2/7/2012 3:15 AM, Kaz Kylheku wrote:
>>>>> I don't want diagnostics; I want strict left to right evaluation order
>>>>> of operands and subexpressions that complete their side effects before
>>>>> yielding a value.
>>>>
>>>> So, what you are really saying, is you want to eliminate most of C's
>>>> optimization abilities, by restricting the order in which the expression
>>>> *must* be evaluated, and side effects *must* be completed?
>>>
>>> Well, no, he isn't saying any such thing. You just made it up. The
>>> fact that evaluation order in C is left to the compilers has very
>>> little to do with optimization; it is a historical artifact that came
>>> from endorsing existing practice when the ANSI standard was put
>>> together. Existing practice then was that compiler writers could do
>>> evaluations in whatever they pleased and they did.

>>
>> No, they did evaluations in the order that made the most sense (i.e. had
>> the best performance) for their particular implementation--and
>> implementations vary.

>
> You are not disagreeing with me.


I disagree that they did "whatever they pleased"; they did what was best
for their particular implementation, for various definitions of "best".

>> For instance, varargs is more straightforward to implement with
>> right-to-left evaluation of arguments, at least with a stack-based
>> calling convention. Order of evaluation may not matter for
>> register-based calling conventions, but if an implementation uses both,
>> it makes sense to use the same order.

>
> Well, yes, I know that. However what you are talking about is a minor
> micro-optimization at most.


It doesn't seem so minor, particularly for platforms where _every_ call
uses a stack-based calling convention. Remember, we're talking about
long ago when compilers were rather dumb and most popular architectures
were register-starved. That is the environment that ANSI was faced
with, and it would have been unreasonable to force the majority of
implementations to suffer a performance penalty for the questionable
benefit of left-to-right evaluation.

> Historically the variations weren't a matter of performance - for the
> most part the performance of the early compilers was less than
> stellar.


Of course; that was the state of the industry at the time. All the more
reason not to make things worse.

> The various choices in calling sequence conventions and in
> parsing order were a mixture of convenience and ad hoc decisions. The
> order variations were an unalterable part of the language by the time
> it came to standardization.


I think we can agree on this much: by the time ANSI looked at the
matter, it was too late to "fix" many of the behaviors that ended up
being called undefined, unspecified or implementation-defined because
doing so would have broken a lot of code that implicitly depended on a
particular implementation's pre-standard behavior.

> In any event the idea that "most of C's optimization abilities" depend
> upon not restricting evaluation order and side effect order is a wild
> exaggeration.


Optimization doesn't depend entirely on that particular gray area, but
gray areas in general provide implementations leeway to make more
aggressive optimizations because they lessen the impact of the "as if"
rule. Allowing the meaning of "a=a++;" to change isn't helpful in
itself, but it may help the compiler optimize _something else_.

Also, most of those gray areas aren't terribly useful in the first place
and avoiding them generally results in clearer code anyway. If _I_
can't figure out what "a=a++;" is supposed to mean, without possibly
resorting to the Standard, it's not important to me that the compiler
knows either because I won't write it in the first place! My primary
audience is human, not machine.

S

--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
 
Reply With Quote
 
Edward A. Falk
Guest
Posts: n/a
 
      02-08-2012
In article <(E-Mail Removed)>,
lujnan <(E-Mail Removed)> wrote:
>Why C Standards Committee does not constrain this case.


Because it's a dumb case. You're not supposed to write that idiom,
and pointless constraints are a bad thing in a system where performance
is king.

--
-Ed Falk, http://www.velocityreviews.com/forums/(E-Mail Removed)
http://thespamdiaries.blogspot.com/
 
Reply With Quote
 
Edward A. Falk
Guest
Posts: n/a
 
      02-08-2012
In article <(E-Mail Removed)>,
Richard Harter <(E-Mail Removed)> wrote:
>
>Well, no, he isn't saying any such thing. You just made it up. The
>fact that evaluation order in C is left to the compilers has very
>little to do with optimization; it is a historical artifact that came
>from endorsing existing practice when the ANSI standard was put
>together.


Perhaps, but it can still have a lot to do with optimization.

Consider:

b = (sqrt(sin(x)*cos(x))) * a;

If the compiler can guess that a is very likely to be zero, and that the
left side is very likely to be expensive, and has no side effects, then
it can generate code that evaluates a first, and then decides whether
or not to evaluate the left side.

I realize that this is a contrived example, but the bottom line is
that C was intended to be a *fast* language, and not a *safe* language.
Why nail the compiler's foot to the floor if you don't have to.

(When I first heard about the C language, it was described to me
as a substitute for assembly language. I think that's the proper
attitude to take when deciding between fast and pedantic.)

--
-Ed Falk, (E-Mail Removed)
http://thespamdiaries.blogspot.com/
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-08-2012
(E-Mail Removed) (Edward A. Falk) writes:
> In article <(E-Mail Removed)>,
> Richard Harter <(E-Mail Removed)> wrote:
>>Well, no, he isn't saying any such thing. You just made it up. The
>>fact that evaluation order in C is left to the compilers has very
>>little to do with optimization; it is a historical artifact that came
>>from endorsing existing practice when the ANSI standard was put
>>together.

>
> Perhaps, but it can still have a lot to do with optimization.
>
> Consider:
>
> b = (sqrt(sin(x)*cos(x))) * a;
>
> If the compiler can guess that a is very likely to be zero, and that the
> left side is very likely to be expensive, and has no side effects, then
> it can generate code that evaluates a first, and then decides whether
> or not to evaluate the left side.
>
> I realize that this is a contrived example, but the bottom line is
> that C was intended to be a *fast* language, and not a *safe* language.
> Why nail the compiler's foot to the floor if you don't have to.


One problem with that contrived example is that the sqrt(), sin(), and
cos() functions can have the side effect of updating errno (if
math_errhandling & MATH_ERRNO is nonzero).

> (When I first heard about the C language, it was described to me
> as a substitute for assembly language. I think that's the proper
> attitude to take when deciding between fast and pedantic.)


I don't disagree. But there's a common misconception that C *is* an
assembly language (its' been called a "high-level assembler). The key
difference is that an assembly language program specifies CPU
instructions, while a C program specifies behavior.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
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
Dynamic Menu Items is not right aligned with Right to Left documen =?Utf-8?B?QmlzaG95?= ASP .Net 0 12-28-2006 11:39 AM
Right-Click With Mouse and Toolba Buttonsr Don't Work Right Bigfoot It Is Computer Support 0 10-30-2006 06:08 PM
Tool to enable Right click on pages where Right click is disabled tsteinke@gmail.com Computer Support 4 08-28-2005 11:53 PM
Tool to right click image in windows explorer and rotate image right or left 90 degrees siliconpi Digital Photography 2 11-29-2004 12:56 PM
pass the right form input to the right control Tom ASP .Net 0 12-11-2003 03:07 AM



Advertisments