String literals, ASCII vs UTF-8

Stephan Bergmann sbergman at redhat.com
Tue Feb 28 23:42:35 PST 2012


On 02/28/2012 02:48 PM, Lubos Lunak wrote:
>   Speaking of the size at the call-site, I good part is the code trying to
> throw std::bad_alloc in case the allocation fails. That actually looks rather
> useless to me, for several reasons:
>
> - not all OUString methods check for this anyway
> - rtl_uString* functions do OSL_ASSERT() after allocations
> - with today's systems (overcommitting, etc.) it is rather pointless to guard
> against allocation failures
>
>   Does somebody see a good reason not to just remove it?

First of all, Linux' memory overcommitting is a bug IMO (and, AFAIU, 
fully optional these days), and should not be misused to justify sloppy 
application design.

Out-of-memory (OOM) is a somewhat curious conditions, as it can occur 
for two rather different reasons (that ask for different solutions), but 
it is not generally possible to tell which is which.  If a system gets 
really low on memory, there is typically little use in trying to carry 
on with an application that experiences OOM, and the best overall 
solution is to terminate the application quickly and as gracefully as 
possible.

However, there are also situations where bad input (malicious or 
otherwise) would cause an application to request excessive amounts of 
memory to do a single task (e.g., open a document), and at least in 
theory the application should be able to cope with such 
externally-induced OOM conditions, by abandoning the bad operation, 
cleaning up after it, telling the user the operation failed, and 
carrying on.

The traditional building blocks for memory acknowledge this dichotomy by 
reporting OOM to the call site (NULL in case of malloc, bad_alloc in 
case of new), as only the call site can decide how to properly react (or 
pass on up the stack to a knowledgeable one).

With LO we are certainly far away from the ideal, where excessive 
operations would be detected and abandoned cleanly, letting the overall 
application continue as if nothing happened.  But I would nevertheless 
not be happy with shaky foundations that ignore OOM and only fail down 
the road when dereferencing a null pointer.  (Even if that "down the 
road" is still nearby, within the same inline function.  It is already 
hard enough to make use of the typical crash report's call stacks, 
always having to judge whether the situation it presents can have 
legitimately occurred, or is due to some earlier memory corruption that 
put wild data into in-use memory.  "Fail fast" is a sound software 
engineering principle, IMO.)

Hence, my preference is still to flag OOM in C++ code with bad_alloc. 
The second best alternative is IMO to abort.

That this OOM handling has to happen in those inline C++ wrapper 
functions is an unfortunate consequence of our C-based low-level API 
(something that we should probably change, if we ever come around to an 
incompatible LO 4 and still are determined to write that in C++).

But how bad is that, anyway?  A little experiment shows that the 
compiler will happily outline those inline functions detecting for 
bad_alloc, creating one instance of them per library.

Stephan


More information about the LibreOffice mailing list