operator new, nothrow and future compatibility doom

408 views
Skip to first unread message

Adrian Taylor

unread,
Mar 5, 2009, 7:02:36 AM3/5/09
to android-ndk
Hi,

I know that the Android libraries do not support C++ exceptions. Fair
enough - but in one specific instance I worry that you are going to
give yourself a compatibility headache in the future.

Android's current C++ "new" operator does not throw exceptions. It
returns NULL if there is insufficient memory.

Standard C++ "operator new" throws a bad_alloc exception in out-of-
memory, unless you pass a "nothrow_t" parameter, in which case it
behaves like your 'new' operator:

MyObject* o = new MyObject(parameters); // throws in out-of-memory
in standard C++
MyObject* o = new (nothrow) MyObject(parameters); // never throws

I tend to think you should be encouraging use of this "nothrow"
parameter in the NDK and in *all* Android platform code. Ideally, the
main "new" operator should simply not link, to ensure nobody is using
it. That way, you can later move to supporting exceptions and be fully
C++-compliant. Whereas as it stands, as soon as you release the NDK,
you'll forever be locked into having a nonstandard non-throwing
operator new.

We've had serious trouble porting code to a certain other mobile
platform which made exactly the same mistake!

Regards

Adrian

David Turner

unread,
Mar 11, 2009, 4:06:42 PM3/11/09
to andro...@googlegroups.com
Hello Adrian,

thanks for bringing this up, we have debated your points internally and here's an official answer.

First of all, we are not going to change the Android sources to use new (nothrow).
Android native libraries are compiled with -fno-exception and there is absolutely zero
chance that we're going to support exceptions in the future. Generally speaking, doing
this would essentially require a complete rewrite of the framework due to various subtle
technical issues (e.g. exception-safe generic containers have different APIs, e.g. they are
not allowed to perform allocation in their constructors).

Moreover, even with today's zero-cost exception schemes, the generated binaries are significantly
larger and this results in slower performance on cpus like the ARM with tiny instruction caches.

Another point raised was that Android implements memory-overcommit in the Linux kernel.
What this means is that a malloc() or new will return a valid virtual memory address even if there is
not enough physical memory to back it on the device. When such an address is first accessed, the
kernel will try to allocate a physical page for it if possible (e.g. by killing other processes). If not, then
your process will simply be killed immediately.

What this means is that it is very unlikely in practice that new() would actually return NULL on Android,
except for a few degenerate cases (e.g. trying to allocate a huge array) which can be detected easily.
Some engineers are even asking me to change the default behaviour to not return NULL, but log an
error message and stack trace and automatically abort the current process (to ease debugging).

Apart from that, I intend to support correct C++ exception-handling code in a future version of the NDK.
This work will probably happen at the same time than adding the support for a reasonably[1] full STL
implementation but is not, unfortunately, of high priority.

Regards

- Digit

[1] By "reasonably full", I mean that we will probably not support wchar_t and various locales.

Adrian Taylor

unread,
Mar 12, 2009, 4:08:55 AM3/12/09
to andro...@googlegroups.com
Hi David,

Thanks for the very full reply. That's all fine; I just wanted to check you hadn't overlooked this potential issue. I'm glad to see you haven't and I hadn't realised you were using overcommit anyway.

Many thanks,

Adrian
Reply all
Reply to author
Forward
0 new messages