## 40079Re: Mainly noise

Expand Messages
• Jul 6, 2005
[ I feel there is much spleen venting going on here ;-) ]

Bram Moolenaar did utter on 06/07/2005 10:40:
> Matthew Winn wrote:
>
>>What does p = func(++p) _mean_? You're assigning two different values
>>to p at the same time: you're trying to give p the value p+1 and the
>>return value of func(). It's like saying int i = 1 = 2 and expecting
>>it to do both. If you mean p = func(p+1) then say p = func(p+1): it'll
>>execute faster and it's easier for readers to understand.
>
> Order of evaluation for "=" is right to left.

No it is not. _Association_ for "=" is right to left, but the order of
evaluation of the operands of the "=" operator is undefined. Given the
expresion a[i] = 2*b; a C compiler is allowed to calculate the memory
address for a[i] before evaluating the value 2*b, but doesn't have to.

> I expect the expression
> on the right to be evaluated before the result is assigned to the lvalue
> on the left. Isn't that what everybody expects?

They may expect it but they would be wrong. Consider the expression
a[i++] = i; with i being 0 - what would you expect, and why? And of
course you will be wrong ;-)

> You can't assign a
> value before you know what the value is...

The issue is that the expression of the object you assign the value to
has to be evaluated as well as the expression that generates the value
being assigned. It is the order of these evaluations that is undefined.

> Another example where order of evaluation matters:
>
> n = (getc(fd) << 8) + getc(fd);
>
> The expression with "+" is evaluated from left to right, thus the first
> read byte is shifted. This is not unusual code, right?
>
> Adding up three byte values and putting the result in the fourth byte:
>
> *p = *p++ + *p++ + *p++;
>
> It's weird, but I don't think that it is unclear about what is expected
> to happen.

That may be so but in both cases it is potentially buggy code. If you
write code for a single platform/processor and it works for you then you
may be happy leaving it as it is, but if you want to write portable
code, including for new processors/platforms yet to appear, it should be
corrected.

>>In the case of expressions like i = ++i both assignments to i have the
>>same value, so it's easy to claim that it's obvious what should happen,
>>but what about less obvious cases? What should
>> int i = 1;
>> i = ++i + ++i;
>>mean? I can think of ways in which that could give any integer result
>>from 2 to 6 depending on the order in which registers are allocated and
>>the way values are incremented and stored. It's easy to say that the
>>compiler should work out what was intended, but if humans can't decide
>>what was intended how can a compiler written by humans do it?
>
>
> If you know that evaluating the expression is done before the assignment
> then it's clear what should happen. But your example is unrealistic,
> there is no point in doing the second increment.
>
> Order of evaluation matters in many cases, thus it's not at all strange
> to define this for the assignment.

Evaluation is defined in terms of "sequence points" not operators. A
sequence point is the point in execution at which all side effects from
an evluation prior to point are complete and no side effects have
started for an evaluation after the point.

> Most notably for C is:
>
> if (p != NULL && *p == 1)
>
> The && operator involves evaluating from left to right, and once it's
> clear the result is False the evaluation stops. This is defined in the
> standard, right? Otherwise a lot of code would break...

The logical operators && and || are special cases since they allow a
speed optimisation in conditional expressions. There are programming
languages where the complete conditional expression is evaluated, which
would result in the above example causing a crash. Who is to say which
is the natural way? This can be very confusing to those new to
short-circuiting conditional expressions.

>>It's poor coding practice not only because the compiler's behaviour is
>>undefined, but also because anyone reading the source has to work harder
>>to determine the intention of the code. If I saw
>> p = vim_strchr(++p, '/');
>>I wouldn't know whether the "++p" was a mistake and should be "p+1", or
>>whether the "p =" was a mistake and the value was being assigned to the
>>wrong variable, or even whether the "++p" was a mistake and the wrong
>>variable was being incremented. As written that code makes no sense,
>>and if I can't work out what it means the compiler certainly shouldn't.
>
> Right, the ++p doesn't make sense here, since the result of the
> increment doesn't need to be stored. The code isn't written like that,
> the increment is done in a macro. The code did make sense before
> expanding the macro. The macro might be suspicious, but isn't using
> macros anyway?

TTFN

Mike
--
There are two ways to handle women. I don't know either one.
• Show all 18 messages in this topic