[cpp-threads] RE: Initial comments on your straw man

Boehm, Hans hans.boehm at hp.com
Fri Feb 24 19:27:06 GMT 2006


I'm not sure whether there was any real conclusion on the issue of what
it means not to interleave function evaluation.

I'll respond to Jason's message in detail below.  I agree that his
interpretation is a plausible way to read the standard.  But I don't
think that much current code is correct with respect to that
interpretation.

I agree with Clark that separate function calls in arguments need to be
strictly isolated; even though they might not be ordered, separate calls
must be allowed to assign to the same scalar object.  My impression is
that current implementations actually guarantee the safety of that by
virtue of the fact that the calls are not interleaved?  But I don't
think Clark's proposal currently states that clearly.  In my opinion, it
should.

My impression is that it's a little ugly to state this.  My take on this
is that we basically need to state that even if they are not otherwise
sequenced, all function calls in a full expression are always sequenced
in some unspecified order.  This is different from what Ben proposed,
and would probably outlaw the second example below, but not the third.
I think it makes sense to outlaw the second example, since we otherwise
need to deal with issues of assignment granularity.  (On a 16-bit
machine, can I assign the top half of i before the call, and the bottom
half after?)  My feeling is that's an issue best avoided.

I will change the strawman proposal to more definitively cite Clark's
paper.  That's clearly a more thorough treatment of the issue, and I
think we should be discussing sequencing in that context.

> -----Original Message-----
> From: Jason Merrill
> Sent: Tuesday, February 21, 2006 7:50 PM
> To: C++ threads standardisation
> Subject: Re: [cpp-threads] RE: Initial comments on your straw man
> 
> Hans Boehm wrote:
> > Which one of the following is legal?
> > 
> > (i = 13) + (i = 14)	-- no
> > (i = 13) + f(&i)	-- not a clue
> > f(&i) + f(&i)	-- yes, otherwise lots of stuff is broken
> > 
> > Probably the middle one should be undefined, but I have no idea how 
> > the standard implies that without also outlawing the last one.
> 
> Clause 5:
> 
> "Between the previous and next sequence point a scalar object 
> shall have its stored value modified at most once by the 
> evaluation of an expression. Furthermore, the prior value 
> shall be accessed only to determine the value to be stored."
> 
> So both lines 2 and 3 are well-formed by themselves. But #2 
> is undefined if f either reads or modifies 'i', and similarly 
> #3 is undefined if f modifies 'i' in one call and reads or 
> modifies it in the other.
> 
Let's assume that f stores through its argument, i.e. modifies i.

My question here really was whether the fact that the calls cannot be
interleaved with other evaluation implies that, at least in the third
case, the sequence points are in fact ordered.

With this interpretation why does something like the non-threaded
Boost/TR1 shared_ptr work at all?  If I pass two shared_ptrs by value as
arguments to a function, and they both happen to point to the same
object, presumably each copy constructor will increment the reference
count, thus resulting in multiple updates between sequence points, and
hence undefined behavior?

I think you get a similar issue if two argument expressions to a
function call both allocate memory using the same mechanism, and thus
both update the same heap data structure.  And there are probably a
zillion other cases like this.

I really don't see how you can outlaw the third case and be left with a
reasonable programming language.  If I understand correctly, you would
have to be able to see through all sorts of abstraction boundaries to
know whether it is legal to use two function calls in the same
expression.

Hans



More information about the cpp-threads mailing list