Re: [hackers] [sbase] Do not rely on `s' being incremented before taking the address of it || sin

From: Rob <robpilling_AT_gmail.com>
Date: Wed, 9 Oct 2013 23:52:30 +0100

On Wed, Oct 09, 2013 at 10:17:28PM +0200, Roberto E. Vargas Caballero wrote:
> > Funnily enough I was doing something similar recently and wondered about
> > that - pretty sure this isn't undefined behaviour, ++s doesn't affect
> > the address of s.
>
> I'm sorry, but you are wrong.

Let's dance!


> > There is only one read and write to `s' going on here, and all the
> > standard says on this is that the write must be performed before the
> > call-sequence-point.
>
> No, standard says that the write must be done before jumping to the
> function, and it explicitly says that calculation of values of the same
> object in the same expression is undefined. In this case, parameters
> can be evaluated from right to left (that is the usual case due to
> printf and varargs function), or from right to left, but in both cases
> the position of memory which holds s, is incremented before jumping
> to strtoul, never after returning of the function. What it means?,
> that in left to right you get: s+1, &(s + 1), 10; but in right to left
> you get: s + 1, s, 10.

Exactly, 'values of the same object' - there's only one value
calculation, the other is taking the address.

So left to right you get:
        s+=1, &s, 10

and right to left you get:
        10, &s, s+=1

The address of `s' doesn't care about the value of `s'. There's no other
"value computation".

> > If a side effect on a scalar object is unsequenced relative to either a
> > different side effect on the same scalar object or a value computation
> > using the value of the same scalar object, the behavior is undefined. If
> > there are multiple allowable orderings of the subexpressions of an
> > expression, the behavior is undefined if such an unsequenced side effect
> > occurs in any of the orderings"
>
> Here is the point, you can not use operators with side effects inside of
> other operators because the behaviour is undefined. Take a look to
> y++ = ++y - y--. Like compilers can choose the evaluation order, maybe
> ++y is performed before than y--, or maybe not. And look again:

Yup - but `s' is only mentioned in an rvalue form once. There's no other
operation on it. &s is using `s' as an lvalue and never performing a
read.

What I'm trying to say is this:

        int s = ...;
        int *p1 = &s;
        s++;
        int *p2 = &s;
        p1 == p2;

s++ doesn't affect p2 or &s.


> > value computations of the operands of an operator are sequenced before
> > the value computation of the result of the operator.
>
> It says the computation of the value, doesn't say anything about side
> effects.

The first line I quoted mentions side effects :)

Your move sir!


Rob
Received on Thu Oct 10 2013 - 00:52:30 CEST

This archive was generated by hypermail 2.3.0 : Thu Oct 10 2013 - 01:00:18 CEST