July 10, 2013
On Wednesday, 10 July 2013 at 17:18:09 UTC, JohnnyK wrote:
> I hope you like the subject matter and I hope it is not too simplistic or have been answered before.
>   Anyway I have a question about how the garbage collector works in a very specific situation.  When passing string type to a function in a shared library or DLL and assigning it to a variable of type string inside the function and returning the internal string.  Such as this.
>
> export string mytest(string tstStr)
> {
>   string st = tstStr;
>   /* abbreviated to protect the innocent but other operations
>      such as concatenating and deleting may be done to st before the return
>   */
>   return st;
> }
>
> Is the string type a pointer or is it something else?  In the line where tstStr is assigned to st does it copy the address in tstStr to st or does it copy the value in tstStr?  I am just a bit confused about string types since I come from a C background and C has no type like this.  Also what is returned by this function?  Does this function return a pointer or the contents of an array?  If I do export this what does it do to the Garbage Collection?  Does the Garbage Collection collect tstStr or st?  Also notice the comment in the function.

Others have answered about how strings and other arrays work (also, see http://dlang.org/arrays.html and http://dlang.org/d-array-article.html), so I'll address the garbage collection question. Shared libraries don't make a difference here AFAIK so we won't worry about them.

The GC will only collect something that there are no live references to. If an array gets reallocated (by e.g. appending to it beyond it's capacity) and there's no reference anywhere to the old data, then it can be collected (no guarantee it will be).
July 11, 2013
On Wednesday, 10 July 2013 at 17:18:09 UTC, JohnnyK wrote:
> export string mytest(string tstStr)
> {
>   string st = tstStr;
>   /* abbreviated to protect the innocent but other operations
>      such as concatenating and deleting may be done to st before the return
>   */
>   return st;
> }


Arrays are complex, as mention see: http://dlang.org/d-array-article.html

The snippet shown, st references the same data as tstStr.

The comment states "concatenating," then st does not point to the same data as tstStr.
July 11, 2013
On Wednesday, 10 July 2013 at 18:22:24 UTC, Ali Çehreli wrote:
> And to be pedantic, length comes first:
>
> struct Array (T)
> {
>     size_t length;
>     T* ptr;
> }
>
> Which is actually property-like because assigning to length does pretty complex stuff. So the member cannot be named as 'length':
>
> struct Array (T)
> {
>     size_t length_;
>     T* ptr;
> }
>
> Anyway... :)
>
> Ali

To be pedantic dynamic arrays are implemented in D simply as

struct Array
{
    size_t length;
    void* ptr;
}

and there is no type parametrization since such arrays handling is opaque for users (in druntime they are treated as void[]). Parametrization can be useful in user side since performing any operations with structure above (void*) will lead to errors. But in user side there is no point in manipulating the structure directly, as it can be done using usual properties/druntime without template bloat. By the way, the style ABI page is written, allows implementation to have more fields.
July 11, 2013
On 2013-07-11 04:59, Maxim Fomin wrote:

> To be pedantic dynamic arrays are implemented in D simply as
>
> struct Array
> {
>      size_t length;
>      void* ptr;
> }
>
> and there is no type parametrization since such arrays handling is
> opaque for users (in druntime they are treated as void[]).
> Parametrization can be useful in user side since performing any
> operations with structure above (void*) will lead to errors. But in user
> side there is no point in manipulating the structure directly, as it can
> be done using usual properties/druntime without template bloat. By the
> way, the style ABI page is written, allows implementation to have more
> fields.

typeof("asd".ptr) gives back immutable(char)*, not immutable(void)*. So from a user point of view it's as if the array is templated.

-- 
/Jacob Carlborg
July 11, 2013
On 2013-07-10 20:22, Ali Çehreli wrote:

> And to be pedantic, length comes first:
>
> struct Array (T)
> {
>      size_t length;
>      T* ptr;
> }

I thought "ptr" came first, that's the reason you could cast to the pointer type. Not that one should do that. Perhaps there's some compiler/runtime magic involved.

-- 
/Jacob Carlborg
July 11, 2013
On Thursday, 11 July 2013 at 07:13:50 UTC, Jacob Carlborg wrote:
> On 2013-07-11 04:59, Maxim Fomin wrote:
>
>> To be pedantic dynamic arrays are implemented in D simply as
>>
>> struct Array
>> {
>>     size_t length;
>>     void* ptr;
>> }
>>
>> and there is no type parametrization since such arrays handling is
>> opaque for users (in druntime they are treated as void[]).
>> Parametrization can be useful in user side since performing any
>> operations with structure above (void*) will lead to errors. But in user
>> side there is no point in manipulating the structure directly, as it can
>> be done using usual properties/druntime without template bloat. By the
>> way, the style ABI page is written, allows implementation to have more
>> fields.
>
> typeof("asd".ptr) gives back immutable(char)*, not immutable(void)*. So from a user point of view it's as if the array is templated.

It's in the user side. In druntime it is void[] + typeinfo. I am not aware of any part in dmd/druntime where arrays are repsented as templates (or strongly typed) as depicted in this dicsussion. And current treatment can be barely called templatization as there is no templates, template instantiations and typicall horrible mangling at all. More precise description is not templatization but some kind of implicit conversion from array of specific type in source code to void array plus typeinfo in runtime library. If user tries to use struct Array(T) {...} instead of usual arrays he will gain no benefit but useless template bloat.
July 11, 2013
On 2013-07-11 09:43, Maxim Fomin wrote:

> It's in the user side. In druntime it is void[] + typeinfo. I am not
> aware of any part in dmd/druntime where arrays are repsented as
> templates (or strongly typed) as depicted in this dicsussion. And
> current treatment can be barely called templatization as there is no
> templates, template instantiations and typicall horrible mangling at
> all. More precise description is not templatization but some kind of
> implicit conversion from array of specific type in source code to void
> array plus typeinfo in runtime library. If user tries to use struct
> Array(T) {...} instead of usual arrays he will gain no benefit but
> useless template bloat.

Yes, but that is easier to type. All the above or:

struct Array (T)
{
    size_t length;
    T* ptr;
}

-- 
/Jacob Carlborg
July 11, 2013
On 2013-07-11 13:19, Jacob Carlborg wrote:

> Yes, but that is easier to type. All the above or:
>
> struct Array (T)
> {
>      size_t length;
>      T* ptr;
> }
>

"that" should have been "what".

-- 
/Jacob Carlborg
July 11, 2013
On 07/11/2013 12:23 AM, Jacob Carlborg wrote:

> On 2013-07-10 20:22, Ali Çehreli wrote:
>
>> And to be pedantic, length comes first:
>>
>> struct Array (T)
>> {
>>      size_t length;
>>      T* ptr;
>> }
>
> I thought "ptr" came first, that's the reason you could cast to the
> pointer type. Not that one should do that. Perhaps there's some
> compiler/runtime magic involved.

There must be little magic and that magic should be the same as getting the .ptr property. Otherwise, the "value" of a struct object cannot be casted to pointer type:

struct S
{
    int *p;
}

    auto s = S();
    int *p = cast(int*)s;

Error: e2ir: cannot cast s of type S to type int*

Ali

July 11, 2013
On Thursday, 11 July 2013 at 17:07:18 UTC, Ali Çehreli wrote:
> On 07/11/2013 12:23 AM, Jacob Carlborg wrote:
>
> > On 2013-07-10 20:22, Ali Çehreli wrote:
> >
> >> And to be pedantic, length comes first:
> >>
> >> struct Array (T)
> >> {
> >>      size_t length;
> >>      T* ptr;
> >> }
> >
> > I thought "ptr" came first, that's the reason you could cast
> to the
> > pointer type. Not that one should do that. Perhaps there's
> some
> > compiler/runtime magic involved.
>
> There must be little magic and that magic should be the same as getting the .ptr property. Otherwise, the "value" of a struct object cannot be casted to pointer type:
>
> struct S
> {
>     int *p;
> }
>
>     auto s = S();
>     int *p = cast(int*)s;
>
> Error: e2ir: cannot cast s of type S to type int*
>
> Ali

In context of slices cast(int*)arr is essentially s.ptr. There is no magic but accessing right field of struct.