On 2 June 2010 13:36, Craig Ringer <craig@postnewspapers.com.au> wrote:
>>
>> Really? That seems like an *incredibly* arduous requirement.
>> Intuitively, I find it difficult to believe. After all, even though
>> using longjmp in C++ code is a fast track to undefined behaviour, I
>> would have imagined that doing so in an isolated C module with a well
>> defined interface, called from C++ would be safe.
>
> Not necessarily. It's only safe if setjmp/longjmp calls occur only
> within the C code without "breaking" call paths involving C++.
It isn't obvious to me that your suggestion that C++ functions that
invoke jumping pg code use only POD types, but manipulate C++ types
through pointers helps much, or at all. RAII/SBRM is just another
memory management strategy (albeit a very effective, intuitive one).
It's basically equivalent to the compiler generating calls to a
constructor when an object is instantiated, and to a destructor when
the object goes out of scope. So, how your concern fundamentally
differs from the general case where we're managing resources (but not
through memory contexts/palloc) explicitly, and risk being cut off
before control flow reaches our (implicit or explicit) destructor call
isn't clear, except perhaps that RAII gives clients what may be a
false sense of security. Sure, one is technically undefined behaviour
while the other isn't, but the end result is probably identical - a
memory leak.
>> I would have
>> imagined that ultimately, the call to the Pg C function must return,
>> and therefore cannot affect stack unwinding within the C++ part of the
>> program.
>
> That's the whole point; a longjmp breaks the call chain, and the
> guarantee that eventually the stack will unwind as functions return.
Yes, but my point was that if that occurs above the C++ code, it will
never be affected by it. We have to longjmp() *over* C++ code before
we have a problem. However, Bruce has answered the question of whether
or not that happens - it does, so I guess it doesn't matter.
Here's a radical idea that has no problems that immediately occur to
me, apart from the two massive problems that you just lost your
ability to reliably manage non-memory resources with RAII, and that
you're now in the realm of undefined behaviour:
Re-implement global operator new() and friends in terms of palloc and
pfree. This sort of thing is often done for C++ application
frameworks.
It makes me queasy that by doing this, we're resorting to undefined
behaviour in terms of the C++ standard (destructors are never called)
as a matter of routine. What do you think? I suppose that such
undefined behaviour is absolutely intolerable. It's not a serious
suggestion, just something that I think is worth pointing out.
--
Regards,
Peter Geoghegan