"Alejandro R. Mosteo" <
alej...@mosteo.com> wrote in message
news:pem7s0$go4$1...@dont-email.me...
> On 26/05/2018 00:22, NiGHTS wrote:
>> I am creating a binding to a C library that requires me to repeat the
>> same function but with a string parameter that changes on each call. I
>> don't want to have to keep creating and destroying string memory for all
>> of these function calls. I would like to create the memory for the string
>> once, allocate enough space so it doesn't need to grow, and reuse that
>> memory for the function call every time I need to pass a new string to
>> it.
>
> I'm currently using this:
>
>
https://github.com/mosteo/cstrings
>
> which is not what you want since it allocates on every instance (although
> on the stack). Still, it might give you some ideas.
>
> I'm still unsure if that's 100% guaranteed to be safe; for the experts out
> here, the question is, in a call to a C function like this:
>
> Call_To_C_Function
> (Function_That_Returns_A_Limited_Tagged_Type (...)
> .Subprogram_That_Returns_A_C_Pointer_To_Data_In_The_Tagged_Type);
>
> Is the in-place built limited tagged type guaranteed to live during the
> call to the C function? (In other words, is the pointer safe (as long as
> the C side does not make a copy, of course)?
That depends on the master of the parameter. I believe that the master of a
parameter is that of the call (each call being it's own master for the
parameters) -- you'd have to look in 7.6.1 to be sure. So they stay around
as long as the call.
If that wasn't true, passing an aggregate could have the temporary object
freed/finalized before the call ended, which would be a disaster.
> My suspicion is that once the subprogram returns the pointer, the limited
> type can be optimized away before the call to the C side. It's not what
> I'm seeing now, but I don't want to depend on an erroneous assumption.
Don't think this is a problem in general -- and the result of a function
does *not* belong to the master of the call but rather the enclosing one
(else you couldn't use it before it went away). You might be able to get it
with nested calls:
Foo (Bar (Ugh (...))
The result of Ugh is finalized when the call to Bar ends, so if it is
somehow in the result of Bar, you could get trouble in Foo. You can avoid
that by declaring the parameter "aliased" (those belong to the *result* of
the function, so they stick around longer).
Randy.