operator new: reconciling sections 18.4 and 5.3.4(13) of the 2003standard

F

forums_mp

Operator new as defined in Section 18.4 of the 2003 edition is as
follows:

void *operator new (size_t) throw
(std::bad_alloc); ///1
void *operator new[] (size_t) throw
(std::bad_alloc); ///2
void *operator new (size_t, const std::nothrow_t&)
throw(); ///3
void *operator new[] (size_t, const std::nothrow_t&)
throw(); ///4


Yet 5.3.4(13) states:

[unless an allocation function is declared with an empty-exception
specification (15.4), throw(), it indicates failure to allocate
storage
by throwing a bad_alloc exception (clause 15, 18.4.2.1); it returns a
non-null pointer otherwise. If the allocation function is declared
with
an empty exception-specification, throw(), it returns null to
indicate
failure to allocate storage and a non-null pointer otherwise. ]

Two questions:
a) Does the reference to 'allocation function is declared with an
empty-exception specification (15.4), throw()' imply items '///3' and
'///4' as shown above?
b) I'm under the impression that section 18.4 is binding, that said,
if I provide overriding definitions then those those definitions ought
to comply with 18.4. True or False?

Thanks in advance
 
P

Pavel

Operator new as defined in Section 18.4 of the 2003 edition is as
follows:

void *operator new (size_t) throw
(std::bad_alloc); ///1
void *operator new[] (size_t) throw
(std::bad_alloc); ///2
void *operator new (size_t, const std::nothrow_t&)
throw(); ///3
void *operator new[] (size_t, const std::nothrow_t&)
throw(); ///4


Yet 5.3.4(13) states:

[unless an allocation function is declared with an empty-exception
specification (15.4), throw(), it indicates failure to allocate
storage
by throwing a bad_alloc exception (clause 15, 18.4.2.1); it returns a
non-null pointer otherwise. If the allocation function is declared
with
an empty exception-specification, throw(), it returns null to
indicate
failure to allocate storage and a non-null pointer otherwise. ]

Two questions:
a) Does the reference to 'allocation function is declared with an
empty-exception specification (15.4), throw()' imply items '///3' and
'///4' as shown above?
My (in no way authoritative) reading is "no". My understanding of 18.4
is that it simply specifies the contents of the standard header <new>
and a programmer can write as many other overloaded (not overriding)
functions for new as s/he wishes
b) I'm under the impression that section 18.4 is binding, that said,
if I provide overriding definitions then those those definitions ought
to comply with 18.4. True or False?
I would say: False. The standard does not forbid defining operator new
function with 5 parameters, for example.
Thanks in advance

Hope this helps,
Pavel
 
J

James Kanze

Operator new as defined in Section 18.4 of the 2003 edition is as
follows:
void *operator new (size_t) throw
(std::bad_alloc); ///1
void *operator new[] (size_t) throw
(std::bad_alloc); ///2
void *operator new (size_t, const std::nothrow_t&)
throw(); ///3
void *operator new[] (size_t, const std::nothrow_t&)
throw(); ///4
Yet 5.3.4(13) states:
[unless an allocation function is declared with an
empty-exception specification (15.4), throw(), it indicates
failure to allocate storage by throwing a bad_alloc exception
(clause 15, 18.4.2.1); it returns a non-null pointer
otherwise. If the allocation function is declared with an
empty exception-specification, throw(), it returns null to
indicate failure to allocate storage and a non-null pointer
otherwise. ]
Two questions:
a) Does the reference to 'allocation function is declared with an
empty-exception specification (15.4), throw()' imply items '///3' and
'///4' as shown above?
Yes.

b) I'm under the impression that section 18.4 is binding, that
said, if I provide overriding definitions then those those
definitions ought to comply with 18.4. True or False?

True.
 
J

James Kanze

Operator new as defined in Section 18.4 of the 2003 edition is as
follows:
void *operator new (size_t) throw
(std::bad_alloc); ///1
void *operator new[] (size_t) throw
(std::bad_alloc); ///2
void *operator new (size_t, const std::nothrow_t&)
throw(); ///3
void *operator new[] (size_t, const std::nothrow_t&)
throw(); ///4
Yet 5.3.4(13) states:
[unless an allocation function is declared with an
empty-exception specification (15.4), throw(), it indicates
failure to allocate storage by throwing a bad_alloc
exception (clause 15, 18.4.2.1); it returns a non-null
pointer otherwise. If the allocation function is declared
with an empty exception-specification, throw(), it returns
null to indicate failure to allocate storage and a non-null
pointer otherwise. ]
Two questions:
a) Does the reference to 'allocation function is declared with an
empty-exception specification (15.4), throw()' imply items '///3' and
'///4' as shown above?
My (in no way authoritative) reading is "no". My understanding
of 18.4 is that it simply specifies the contents of the
standard header <new> and a programmer can write as many other
overloaded (not overriding) functions for new as s/he wishes>

But he's asking here about the functions defined in the library
(which you can replace). The semantics of these functions are
in part defined by the fact that one has an empty exception
specification, and the other doesn't. And that the functions
must obey the rules of §5.3.4.

You can, of course, provide additional overloads for operator
new, which have different semantics. They still have to obey
the more general rules of §5.3.4: if your operator new has an
empty exception specification, it reports errors by returning a
null pointer; otherwise, it reports them by throwing bad_alloc
(or something derived from bad_alloc).
b) I'm under the impression that section 18.4 is binding, that said,
I would say: False. The standard does not forbid defining
operator new function with 5 parameters, for example.

But such a definition wouldn't override the definitions in the
standard; it would overload them.
 
F

forums_mp


First things first, thanks for the clarification. Pavel's response
made me semi nervous. A follow up question: 5.3.4(13) talks about an
allocation function throwing std::bad_alloc or returing a null pointer
on failure to allocate storage.

5.3.4 (8) says:
"A new-expression obtains storage for the object by calling an
allocation function (3.7.3.1). If the new expression terminates by
throwing an exception, it may release storage by calling a
deallocation function
(3.7.3.2)."

The new expression does not 'throw' an exception does it? Its the
allocation function that does. 5.3.4(8) more specifically "new
expression terminates by throwing an exception" seems somewhat
misleading to me.
 
B

Bart van Ingen Schenau

5.3.4 (8) says:
"A new-expression obtains storage for the object by calling an
allocation function (3.7.3.1). If the new expression terminates by
throwing an exception, it may release storage by calling a
deallocation function
(3.7.3.2)."

The new expression does not 'throw' an exception does it?  Its the
allocation function that does.  5.3.4(8) more specifically "new
expression terminates by throwing an exception" seems somewhat
misleading to me.

You have to remember that the new expression comprises of *two*
actions, both of which can possibly throw an exception:
1. Call the allocation function to obtain some memory
2. Invoke the constructor to create an object in the allocated memory.

Bart v Ingen Schenau
 
J

James Kanze

First things first, thanks for the clarification. Pavel's
response made me semi nervous. A follow up question:
5.3.4(13) talks about an allocation function throwing
std::bad_alloc or returing a null pointer on failure to
allocate storage.
5.3.4 (8) says:
"A new-expression obtains storage for the object by calling an
allocation function (3.7.3.1). If the new expression terminates by
throwing an exception, it may release storage by calling a
deallocation function
(3.7.3.2)."
The new expression does not 'throw' an exception does it? Its
the allocation function that does. 5.3.4(8) more specifically
"new expression terminates by throwing an exception" seems
somewhat misleading to me.

No, but it calls an allocator function and a constructor, either
of which may throw an exception. The wording could possibly be
better, but I think the meaning is clear: if the new expression
is terminated as a result of an expression propagating out of
it, the compiler may generate code which frees the memory. The
exact conditions under which it will call the deallocator
function are specified in §5.3.4/17.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top