The new operator with an empty constructor for calling the exception specification when returning distribution 0

I have the following declaration:

void * operator new (size_t s, PersistentMemory * m) throw() {return m->allocatePersistentMemory(s);} 

I test running out of memory at startup, which results in m->allocatePersistentMemory(s); 0. The new then calls the null pointer constructor for this

However, based on 3.7.3.1 paragraph 3 of the C ++ 2003 standard:

A distribution function that cannot allocate storage can call currently set new_handler (18.4.2.2), if any. [Note: A software distribution function can get the address of the currently set new_handler using the set_new_handler function (18.4.2.3). ] If the distribution function is declared with an empty specification exception (15.4), throw () does not allow allocating storage, this should return a null pointer. Any other distribution function that does not work for storage distribution is indicated only by a failure, throwing an exception to the std :: bad_alloc class (18.4.2.1) or a class derived from std :: bad_alloc.

The way I understand it is that if m->allocatePersistentMemory(s) return null should lead to returning the whole operator new() throw() null without calling the constructor. Am I missing some other condition elsewhere that cancels this?

Thanks!

+4
source share
2 answers

I suspect that you are not calling new , which you think you are calling.

It works as you expect.

 void *myalloc (size_t) { return 0; } void * operator new (size_t s) throw() { return myalloc(s); } struct Foo { std::string s; Foo () { std::cout << this << std::endl; } }; int main () { Foo *f = new Foo; if (f == 0) std::cout << "f is NULL" << std::endl; } 

Where how, it fails.

 void *myalloc (size_t) { return 0; } void * operator new (size_t s) throw() { return myalloc(s); } struct Foo { std::string s; Foo () { std::cout << this << std::endl; } void * operator new (size_t s) { return myalloc(s); } }; int main () { Foo *f = new Foo; if (f == 0) std::cout << "f is NULL" << std::endl; } 
+2
source

Section 5.3.4 (13) of the C ++ 03 standard states:

[Note: if the distribution function is not declared with an empty specification exception (15.4), throw() , this indicates that the storage is being distributed, throwing a bad_alloc exception (clause 15, 18.4.2.1); it returns a non-zero pointer otherwise. If the distribution function is declared with an empty exception specification, throw() , it returns null to indicate the inability to allocate storage and a non-empty pointer otherwise. ] If the distribution function returns null, initialization fails, the release function should not be called, and the value of the new expression should be zero.

The phrase “initialization should not be executed” means that the constructor will not be called.

Interesting - and if I don't read the specification incorrectly - when your distribution function points to throw() and returns null, the call value of the "newest" one is null. I always thought this was impossible (see, for example, almost every answer in Will there be a new return NULL anyway? ).

+2
source

All Articles