Topic: Value of pointer if new expr throws
Author: Scott Meyers <NeverRead@aristeia.com>
Date: Wed, 17 Feb 2010 11:16:43 CST Raw View
From a colleague:
> When you have an allocation, initialization, and assignment, as in
>
> Node *n = 0;
> ~~~
> n = new Node(init);
>
> We know that if the allocation of memory for Node succeeds and the
> constructor for Node throws, then the allocated memory will be recovered
> by the corresponding operator delete.
>
> However, I think that the compiler is allowed to do the assignment of
> the address to n BEFORE the constructor is called. If that's the case,
> then the value of n (formerly null) will be corrupted if the constructor
> throws an exception; n will point to deleted memory.
>
> Therefore I claim that the code should be written as follows:
>
> Node *n = 0;
> ~~~
> Node *tmp = new Node(init);
> n = tmp;
>
> Is this your understanding as well, or am I wrong about this?
I can't find anything in the C++03 standard that guarantees that in
n = new Node(init);
n won't be modified if the new expression throws. Am I overlooking something,
or is my colleague correct?
Please note that this question is about the current standard (C++03), not C++0x.
Thanks,
Scott
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Gert-Jan de Vos <gert-jan.de.vos@onsneteindhoven.nl>
Date: Wed, 17 Feb 2010 16:26:38 CST Raw View
On Feb 17, 6:16 pm, Scott Meyers <NeverR...@aristeia.com> wrote:
> From a colleague:
>
>
>
> > When you have an allocation, initialization, and assignment, as in
>
> > Node *n = 0;
> > ~~~
> > n = new Node(init);
>
> > We know that if the allocation of memory for Node succeeds and the
> > constructor for Node throws, then the allocated memory will be recovered
> > by the corresponding operator delete.
>
> > However, I think that the compiler is allowed to do the assignment of
> > the address to n BEFORE the constructor is called. If that's the case,
> > then the value of n (formerly null) will be corrupted if the constructor
> > throws an exception; n will point to deleted memory.
>
> > Therefore I claim that the code should be written as follows:
>
> > Node *n = 0;
> > ~~~
> > Node *tmp = new Node(init);
> > n = tmp;
>
> > Is this your understanding as well, or am I wrong about this?
>
> I can't find anything in the C++03 standard that guarantees that in
>
> n = new Node(init);
>
> n won't be modified if the new expression throws. Am I overlooking
something,
> or is my colleague correct?
>
> Please note that this question is about the current standard (C++03), not
C++0x.
>
> Thanks,
>
> Scott
1.9-17 describes the sequence points at function entry and exit:
"... There is also a sequence point after the copying of a returned
value
and before the execution of any expressions outside the function 11).
Several contexts in C++ cause evaluation of a function call, even
though
no corresponding function call syntax appears in the translation unit.
[Example: evaluation of a new expression invokes one or more
allocation
and constructor functions; see 5.3.4. ..."
This could be interpreted as no sequence point at constructor exit as
a
constructor does not return a value. Footnote 11) clarifies this:
"11) The sequence point at the function return is not explicitly
specified
in ISO C, and can be considered redundant with sequence points at
full-
expressions, but the extra clarity is important in C++. In C++, there
are
more ways in which a called function can terminate its execution, such
as
the throw of an exception."
Now to me it is still unclear whether the return of a constructor
function is
a sequence point.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 17 Feb 2010 17:55:02 CST Raw View
On 17 Feb., 18:16, Scott Meyers <NeverR...@aristeia.com> wrote:
> From a colleague:
> > When you have an allocation, initialization, and assignment, as in
>
> > Node *n = 0;
> > ~~~
> > n = new Node(init);
>
> > We know that if the allocation of memory for Node succeeds and the
> > constructor for Node throws, then the allocated memory will be recovered
> > by the corresponding operator delete.
>
> > However, I think that the compiler is allowed to do the assignment of
> > the address to n BEFORE the constructor is called. If that's the case,
> > then the value of n (formerly null) will be corrupted if the constructor
> > throws an exception; n will point to deleted memory.
>
> > Therefore I claim that the code should be written as follows:
>
> > Node *n = 0;
> > ~~~
> > Node *tmp = new Node(init);
> > n = tmp;
>
> > Is this your understanding as well, or am I wrong about this?
>
> I can't find anything in the C++03 standard that guarantees that in
>
> n = new Node(init);
>
> n won't be modified if the new expression throws. Am I overlooking something,
> or is my colleague correct?
>
> Please note that this question is about the current standard (C++03), not C++0x.
The C++03 standard does not specify that clearly, see the
discussion among
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#672
HTH & Greetings from Bremen,
Daniel Kr gler
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]