If I want to allocate memory, but handle it gracefully if it fails, what are the recommended approaches?
You could call GetMemPtr directly (with all the drawbacks of using GetMem vs. New, as you know), or install your own allocator (wrapper) which returns `UndocumentedReturnNil' (as, e.g. BPGetMem in the System unit does). As the name indicates, this was really a quick kludge, added to support this BP compatibility unit ...
Sounds ugly. Does this mean the compiler actually does cope with New returning nil? Ie, it wont call Initialize?
I don't think we have a really nice way to do it ATM.
Is there (or perhaps should there be) a way to disable the run time error temporarily and manage to return New with a nil value? If the compiler already copes with New potentially returning nil, then presumably all it would need would be a flag to heap.pas to return nil without a runtime error? It looks like heap.pas would need to be a little more careful with how it copes with nil (for example, currently AddToMarkList and AddHeapRange would be called if GetMemPtr^ was allowed to return nil without generating a runtime error.
New( s, 10 ); if s <> nil then
is much cleaner than
s := GetMemPtr^( SizeOf(String(10)) ); if s <> nil then begin Initialize(s^);
I presume the two sequences of code would be equivalent if the runtime error in New was avoided and returned nil instead.
I'm happy to add support for a flag in heap.pas if that is desired, assuming that it wont have any affect on the compiler and the compiler already does handle the New returning nil case.
Thanks, Peter.