Sven Panne <[EMAIL PROTECTED]> wrote,
> Marcin 'Qrczak' Kowalczyk wrote:
> > The function is described as unsafe because the result loses the
> > finalizer, right? [...]
>
> Not exactly. The real problem (pointed out to me by Manuel Chakravarty
> some time ago) is exemplified by the following code snippet:
>
> addr <- foreignObjToAddr fo -- last reference of `fo'
> -- Murphy's Law strikes again: GC is happening exactly here
> res <- someExternalFunction addr -- dangling reference :-(
>
> Passing foreign objects directly via the FFI does not have this
> problem, because there is a special lifetime guarantee for this
> kind of values. :-P
Actually, doesn't that prove the point that I tried to make
when we discussed this previously, namely that the "special
lifetime guarantee" isn't a very good idea in the first
place? It's a kludge. As soon as a ForeignObj is not
passed as an explicit argument to a C function, but as part
of a compound data structure, the kludge breaks.
As SimonM said in a previous email (and Michael Weber
pointed out in our earlier discussion), if you pass a
ForeignObj to C and want to be sure that it doesn't get
finalised, you have to StablePtr it. Why should there be a
difference between the case where the ForeignObj is passed
as an individual argument and the case where it is passed as
part of a compound structure?
The only excuse that I see at the moment is that the special
lifetime guarantee saves some typing in the common case -
not a very good excuse for an awkward language feature,
I think. Especially, as we can handle this case also nicely
in the FFI marshaling library (by providing a wrapper that
does the `StablePtr'ing).
Manuel