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

From: Roberto E. Vargas Caballero <>
Date: Wed, 9 Oct 2013 22:17:28 +0200

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

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

> "An expression is a sequence of operators and operands that specifies
> computation of a value, or that designates an object or a function, or
> that generates side effects, or that performs a combination thereof. The
> value computations of the operands of an operator are sequenced before
> the value computation of the result of the operator.

This is obvious, you can not calculate something whose operands you don't

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

> 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

> paragraphs out of the way, so we can cut the 10 lines back down to 2.

I agree with you here, but I think the solution is only this small patch:

- r->max = (*s == '-') ? strtoul(++s, &s, 10) : r->min;
+ r->max = (*s == '-') ? strtoul(s + 1, &s, 10) : r->min;
+ s++;

Roberto E. Vargas Caballero
'Write programs that do one thing and do it well. Write programs to work
together. Write programs to handle text streams, because that is a
universal interface'
(Doug McIlroy)
In Other Words - Don't design like polkit or systemd
Received on Wed Oct 09 2013 - 22:17:28 CEST

This archive was generated by hypermail 2.3.0 : Wed Oct 09 2013 - 22:24:14 CEST