Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Does memory allocation is allowed to interrupt function argument evaluation?

40 views
Skip to first unread message

Dmitry Potapov

unread,
Feb 14, 2012, 5:39:28 AM2/14/12
to
Hello everyone,

As everyone knows, in «new my_class(my_arg);» statement, it is not
specified what will occur first, memory allocation or argument
evaluation. Is there any guarantee, that memory allocation won't occur
during argument evaluation?
I.e. in the following statement:
new my_class(another_class(third_class(1)));

Does standard guarantee that memory allocation won't occur after
third_class construction but before another_class construction?

--
Thanks in advance,
Dmitry


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Daniel Krügler

unread,
Feb 14, 2012, 8:14:32 PM2/14/12
to
On 2012-02-14 11:39, Dmitry Potapov wrote:
> As everyone knows, in «new my_class(my_arg);» statement, it is not
> specified what will occur first, memory allocation or argument
> evaluation. Is there any guarantee, that memory allocation won't occur
> during argument evaluation?

No.

> I.e. in the following statement:
> new my_class(another_class(third_class(1)));
>
> Does standard guarantee that memory allocation won't occur after
> third_class construction but before another_class construction?

There exists no such guarantee. The problem you are referring to was resolved by

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#672

From FDIS, [expr.new] p16:

"The invocation of the allocation function is indeterminately sequenced with respect to the evaluations of expressions in the new-initializer. Initialization of the allocated object is sequenced before the value computation of the new-expression. It is unspecified whether expressions in the new-initializer are evaluated if the allocation function returns the null pointer or exits using an exception."

Maybe you could explain us a bit what you particular concerns are in regard to this wording state? Why do you need this ordering guarantee?

HTH & Greetings from Bremen,

Daniel Krügler

Goran

unread,
Feb 14, 2012, 8:19:28 PM2/14/12
to
On Feb 14, 11:39 am, Dmitry Potapov <potapo...@gmail.com> wrote:
> Hello everyone,
>
> As everyone knows, in «new my_class(my_arg);» statement, it is not
> specified what will occur first, memory allocation or argument
> evaluation. Is there any guarantee, that memory allocation won't occur
> during argument evaluation?
> I.e. in the following statement:
> new my_class(another_class(third_class(1)));
>
> Does standard guarantee that memory allocation won't occur after
> third_class construction but before another_class construction?

I don't think it does, but would like to see a situation in which this
question needs an answer ;-).

Goran.

Martin Bonner

unread,
Feb 14, 2012, 8:19:30 PM2/14/12
to
On Feb 14, 10:39 am, Dmitry Potapov <potapo...@gmail.com> wrote:
> Hello everyone,
>
> As everyone knows, in «new my_class(my_arg);» statement, it is not
> specified what will occur first, memory allocation or argument
> evaluation. Is there any guarantee, that memory allocation won't occur
> during argument evaluation?
> I.e. in the following statement:
> new my_class(another_class(third_class(1)));
>
> Does standard guarantee that memory allocation won't occur after
> third_class construction but before another_class construction?

a) I doubt it.
b) How would you tell? If you can't (in a standard compliant
program), then the question becomes meaningless.

Dmitry Potapov

unread,
Feb 15, 2012, 3:10:26 PM2/15/12
to
For example (just example, but illustrates situation I have):
void binary_tree::unite(const iface& tree)
{
node_impl = new binary_tree_node(node_impl, std::auto_ptr<impl>(tree->clone()));
}

In the example above I need to be sure that after iface::clone() execution,
\the pointer returned will be acquired by std::auto_ptr (or std::unique_ptr
or any other lightweight smart pointer) before calling allocation function,
which can throw exception.

For now, I store std::auto_ptr in separate local variable:
std::auto_ptr<impl> right_subtree(tree->clone());
node_impl = new binary_tree_node(node_impl, right_subtree);

But using such constructions won't allow compiler to apply copy elision of
second argument of binary_tree_node c'tor.

Goran

unread,
Feb 16, 2012, 1:20:38 AM2/16/12
to
On Feb 15, 9:10 pm, Dmitry Potapov <potapo...@gmail.com> wrote:
> For example (just example, but illustrates situation I have):
> void binary_tree::unite(const iface& tree)
> {
> node_impl = new binary_tree_node(node_impl, std::auto_ptr<impl>(tree->clone()));
>
> }
>
> In the example above I need to be sure that after iface::clone() execution,
> \the pointer returned will be acquired by std::auto_ptr (or std::unique_ptr
> or any other lightweight smart pointer) before calling allocation function,
> which can throw exception.
>
> For now, I store std::auto_ptr in separate local variable:
> std::auto_ptr<impl> right_subtree(tree->clone());
> node_impl = new binary_tree_node(node_impl, right_subtree);

That's what I do, too.

>
> But using such constructions won't allow compiler to apply copy elision of
> second argument of binary_tree_node c'tor.

Copy elision of an auto_ptr? That's all inline anyhow. You care about
that? Hmmm...

All that said, you might find make_unique from Sutter's Mill (http://
herbsutter.com/gotw/_102/) relevant.

Goran.
0 new messages