Topic: ++var and throw
Author: David R Tribble <david@tribble.com>
Date: 1999/09/27 Raw View
Ed Brey <brey@afd.mke.etn.com> writes:
>> In the spirit of the ++var thread, I have a spin-off question (I
>> coincidentally just ran into this while doing real work). Consider
>> the statement:
>>
>> *p++ = f();
>
>> If f() throws, is p guaranteed to not be incremented? Where does
>> the IS define this or say that it is undefined?
>> ...
>> I hope that does not mean that it can be interrupted by the throw
>> of an exception because that could leave p in an unstable state.
Steve Clamage wrote:
> The expression statement has two side effects:
> 1. assignment to *p
> 2. modifying p by incrementing its value
>
> Side effects cannot be delayed beyond reaching the applicable
> sequence point. Whether completion occurs sooner than the sequence
> point is unspecified. [...]
>
> You therefore should not write code that depends for correctness
> on multiple side effects in expressions, if exceptions can occur.
Exactly; don't do it. Do something instead that will leave p in a
well-defined state, such as:
*p = f(); // might throw, p is unchanged
p++; // now p is changed safely
// (assuming p is not an iterator)
When you play with fire (exceptions), expect to get burned once in
a while.
-- David R. Tribble, david@tribble.com --
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James.Kanze@dresdner-bank.com
Date: 1999/09/24 Raw View
In article <JxzHwHAhRS63Ew3l@robinton.demon.co.uk>,
Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>
> In article <7sb2gi$qbg3@interserv.etn.com>, Ed Brey
> <brey@afd.mke.etn.com> writes
> >In the spirit of the ++var thread, I have a spin-off question (I
> >coincidentally just ran into this while doing real work). Consider
the
> >statement:
> >*p++ = f();
> >If f() throws, is p guaranteed to not be incremented? Where does the
> >IS define this or say that it is undefined?
> I do not think there are any guarantees. f() can be evaluated before
> or after *p, the side-effect caused by ++ (writing back to p) can
> happen anytime before completion of the whole expression. I hope that
> does not mean that it can be interrupted by the throw of an exception
> because that could leave p in an unstable state.
This is an interesting question. You don't need exceptions to see the
problem; all it takes is for p to be global and accessible by f. It
isn't hard to imagine a machine on which updating a pointer required two
writes. If the compiler is allowed to insert the call to f between the
two writes, and f accesses p, then you could get undefined behavior.
(If the update is required to be atomic, f might see the value before
incrementation, or after, but in both cases, it could at least legally
look at the pointer.)
I'm unable to find any exact words to cover this, but I'm pretty sure
that the intend is that this should work (both in C and C++).
Note too that the call to f introduces a sequence point. According to
the standard, at a sequence point, all volatile values are reputed
stable. As I understand it, however, in the abstract machine described
by the standard, there is no real difference between volatile variables
and non volatile variables -- the volatile-ness simply indicates whether
the behavior is observable or not.
Of course, if the above counts on the sequence point of the function
call to be defined, we have a problem with:
*p ++ = (throw 1 , 0) ;
(The comma operator introduces a sequence point, but it is irrelevant,
because the code throws before, and throw is not a sequence point.)
--
James Kanze mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient e objet/
Beratung in objekt orientierter Datenverarbeitung
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/24 Raw View
>> In article <7sb2gi$qbg3@interserv.etn.com>, Ed Brey
>>> *p++ = f();
I'm not sure if this is relevant, but check it out.
http://www.cntc.com/resources/gotw055.html
--
--------------
siemel b naran
--------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: clamage@eng.sun.com (Steve Clamage)
Date: 1999/09/23 Raw View
"Ed Brey" <brey@afd.mke.etn.com> writes:
>In the spirit of the ++var thread, I have a spin-off question (I
>coincidentally just ran into this while doing real work). Consider the
>statement:
>*p++ = f();
>If f() throws, is p guaranteed to not be incremented? Where does the IS
>define this or say that it is undefined?
The expression statement has two side effects:
1. assignment to *p
2. modifying p by incrementing its value
Side effects cannot be delayed beyond reaching the applicable
sequence point. Whether completion occurs sooner than the sequence
point is unpsecified.
There are two sequence points in the statement:
1. The arguments to f must be fully evaluated along with their side
effects before f is entered. Since f has no arguments, this
requirement has no effect.
2. All side effects of the expression statement must be complete
at the end of the full-expression (the semicolon in this case).
If f exits via an exception, we never reach the end of the full-
expression, and thus do not reach the sequence point. It is
therefore unspecified whether p is incremented.
You therefore should not write code that depends for correctness
on multiple side effects in expressions, if exceptions can occur.
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/09/22 Raw View
In the spirit of the ++var thread, I have a spin-off question (I
coincidentally just ran into this while doing real work). Consider the
statement:
*p++ = f();
If f() throws, is p guaranteed to not be incremented? Where does the IS
define this or say that it is undefined?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/22 Raw View
In article <7sb2gi$qbg3@interserv.etn.com>, Ed Brey
<brey@afd.mke.etn.com> writes
>
>In the spirit of the ++var thread, I have a spin-off question (I
>coincidentally just ran into this while doing real work). Consider the
>statement:
>
>*p++ = f();
>
>If f() throws, is p guaranteed to not be incremented? Where does the IS
>define this or say that it is undefined?
I do not think there are any guarantees. f() can be evaluated before or
after *p, the side-effect caused by ++ (writing back to p) can happen
anytime before completion of the whole expression. I hope that does not
mean that it can be interrupted by the throw of an exception because
that could leave p in an unstable state.
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1999/09/22 Raw View
In article <7sb2gi$qbg3@interserv.etn.com>,
Ed Brey <brey@afd.mke.etn.com> wrote:
>
>In the spirit of the ++var thread, I have a spin-off question (I
>coincidentally just ran into this while doing real work). Consider the
>statement:
>
>*p++ = f();
>
>If f() throws, is p guaranteed to not be incremented? Where does the IS
>define this or say that it is undefined?
I don't think it specifies this. There's no sequence point in an
assignment, and order of evaluation is not specified. This could be
compiled as:
reg = p;
p++;
*reg = f();
or
reg = p;
*reg = f();
p++;
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1999/09/23 Raw View
Ed Brey wrote:
>
> In the spirit of the ++var thread, I have a spin-off question (I
> coincidentally just ran into this while doing real work). Consider the
> statement:
>
> *p++ = f();
>
> If f() throws, is p guaranteed to not be incremented? Where does the IS
> define this or say that it is undefined?
There is no sequence point anywhere within that expression. Therefore, the
parts of it may be evaluated in any order. Even if the operators were
user-defined member functions, there's no guarantee of the order in which
they'll be called.
If you wrote "f(*p++);", then things would be different, because there is a
sequence point between the evaluation of any function's arguments and the
body of the function itself, so the increment will have taken place.
Sequence points are described in section 1.9 of the standard.
--
Ciao, Paul D. DeRocco
Paul mailto:pderocco@ix.netcom.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/23 Raw View
On 22 Sep 1999 18:08:16 GMT, Ed Brey <brey@afd.mke.etn.com> wrote:
>In the spirit of the ++var thread, I have a spin-off question (I
>coincidentally just ran into this while doing real work). Consider the
>statement:
>
>*p++ = f();
>
>If f() throws, is p guaranteed to not be incremented? Where does the IS
>define this or say that it is undefined?
We can't make such a garauntee.
First note that the above is the same as,
operator= ( operator* ( operator++(p,0) ) , f() );
The compiler may evaluate the above expression in any of these two
orderings:
"f()" first, "operator*(operator++(p,0))" second
the other way around -- for 2 total possible orderings
The compiler may also interleave the evaluations
"f()" first, "operator++(p,0)" second, "operator*(...)" third
other orderings -- for 6 total possible orderings
The compiler may also do some evaluations simultaneously.
--
--------------
siemel b naran
--------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]