Thread overview
Structs as reference types?
May 29, 2021
sighoya
May 29, 2021
Alexandru Ermicioi
May 29, 2021
Alexandru Ermicioi
May 30, 2021
tsbockman
May 30, 2021
evilrat
May 30, 2021
Alexandru Ermicioi
May 30, 2021
sighoya
May 30, 2021
Alexandru Ermicioi
May 30, 2021
Alexandru Ermicioi
May 30, 2021
sighoya
May 29, 2021

What about:

ptr struct S
{
     int i;
}
void main()
{
    S s = S(1);
    writeln("s: ",s.i); //1
}

instead of:

struct _S
{
    int i;
}

alias S = _S*;
alias init(T:S) = (i) {return new PointerTarget!T(i);};//return new _S(i)

void main()
{
    S s = init!S(1);
    writeln("s: ",s.i);//1
}
May 29, 2021

On Saturday, 29 May 2021 at 18:34:44 UTC, sighoya wrote:

>

What about:

ptr struct S
{
     int i;
}
void main()
{
    S s = S(1);
    writeln("s: ",s.i); //1
}

That is literally a final class:

final class S {
int s;
}

void main() {
S s = new S();
writeln("s: ", s.i);
}

Best regards,
Alexandru.

May 29, 2021

On Saturday, 29 May 2021 at 18:40:40 UTC, Alexandru Ermicioi wrote:

>

...

Sorry didn't know some char sequences change the font size, it was intended for it to be a block of code similar to one in ddoc.

May 30, 2021

On Saturday, 29 May 2021 at 18:40:40 UTC, Alexandru Ermicioi wrote:

>

On Saturday, 29 May 2021 at 18:34:44 UTC, sighoya wrote:

>

What about:

ptr struct S
{
     int i;
}
// ...

That is literally a final class:

final class S {
int s;
}

No, a final class in D still has a size_t.sizeof * 2 header containing a virtual function table pointer and a monitor, because all extern(D) classes are implicitly derived from Object:

struct SS
{
	int i;
}
pragma(msg, SS.sizeof); // 4
pragma(msg, is(SS : Object)); // false

final class CS {
    int i;
}
pragma(msg, __traits(classInstanceSize, CS)); // 20 (with 64-bit architecture)
pragma(msg, is(CS : Object)); // true

Aside from the wasted space, the final class version isn't compatible with extern(C) interfaces like the struct version is.

May 30, 2021

On Sunday, 30 May 2021 at 00:39:59 UTC, tsbockman wrote:

>

On Saturday, 29 May 2021 at 18:40:40 UTC, Alexandru Ermicioi wrote:

>

On Saturday, 29 May 2021 at 18:34:44 UTC, sighoya wrote:

>

What about:

ptr struct S
{
     int i;
}
// ...

That is literally a final class:

final class S {
int s;
}

No, a final class in D still has a size_t.sizeof * 2 header containing a virtual function table pointer and a monitor, because all extern(D) classes are implicitly derived from Object:

struct SS
{
	int i;
}
pragma(msg, SS.sizeof); // 4
pragma(msg, is(SS : Object)); // false

final class CS {
    int i;
}
pragma(msg, __traits(classInstanceSize, CS)); // 20 (with 64-bit architecture)
pragma(msg, is(CS : Object)); // true

Aside from the wasted space, the final class version isn't compatible with extern(C) interfaces like the struct version is.

extern(C++) class doesn't have monitor so it's just single pointer size for typeinfo.

extern(C++)
class test
{
}

pragma(msg, __traits(classInstanceSize, test)); // 8
pragma(msg, (void*).sizeof); // 8
pragma(msg, __traits(allMembers, test));  // tuple()  no members at all

about allmembers, D class usually have these "tuple("toString", "toHash", "opCmp", "opEquals", "Monitor", "factory")" and size of 16 (one extra pointer) for monitor.

May 30, 2021

On Sunday, 30 May 2021 at 00:39:59 UTC, tsbockman wrote:

>

No, a final class in D still has a size_t.sizeof * 2 header containing a virtual function table pointer and a monitor, because all extern(D) classes are implicitly derived from

>

Aside from the wasted space, the final class version isn't compatible with extern(C) interfaces like the struct version is.

From the looks of the request, what he wanted is to have mainly reference semantics, which classes already have.

Well true, it is fatter if not marked as extern(c++) as evilrat mentioned.

It would be nice if the proto object proposal would get implemented. It would cleanse a bit the Object hierarchy and would allow use classes as structs (well still a bit fatter) without extern (c++).

May 30, 2021

On Sunday, 30 May 2021 at 07:04:29 UTC, Alexandru Ermicioi wrote:

>

From the looks of the request, what he wanted is to have mainly reference semantics, which classes already have.

My gut feeling is that structs are in favor toward classes. Both aren't really interconvertible and if you don't use templated code you have to decide between structs, classes and interfaces.
Examples are the container structures in D which seem to be stucts. We may say that passing them by value is optimized out, however value fields have still to be copied in certain cases which is unnecessary.
Passing them by ref is fine but that holds only for stack allocated structs? Moreover, there are no ref T types making it hard to instantiate type parameters with ref structures.

For heap structs, we have pointers, but it sucks to create aliases all the time to hide the pointer in the name of the pointer struct.

>

It would be nice if the proto object proposal would get implemented. It would cleanse a bit the Object hierarchy and would allow use classes as structs (well still a bit fatter) without extern (c++).

Interesting, did you have a link.

Further, I'm also in favor of adding:

ref struct S
{
   int i;
}

which wouldn't be covered by the proposal?
Really, I would like to make structs and classes more equatable to each other, switching between them sucks.

May 30, 2021

On Sunday, 30 May 2021 at 11:17:03 UTC, sighoya wrote:

>

On Sunday, 30 May 2021 at 07:04:29 UTC, Alexandru Ermicioi wrote:

>

From the looks of the request, what he wanted is to have mainly reference semantics, which classes already have.

My gut feeling is that structs are in favor toward classes. Both aren't really interconvertible and if you don't use templated code you have to decide between structs, classes and interfaces.
That's the point, each of them has their own use. What use cases are trying to cover by having ptr struct type?
Examples are the container structures in D which seem to be stucts. We may say that passing them by value is optimized out, however value fields have still to be copied in certain cases which is unnecessary.
They are usually structs because, most of containers will also want to inherit atributes of the struct methods (it's operator overloads) such as @safe, pure, @nogc and etc. if, you're referring to custom containers. It is literally impossible to design a collection interface that will inherit attributes from the structure it will hold.

>

Passing them by ref is fine but that holds only for stack allocated structs?
Ref should work for heap allocated ones too, you just need to dereference them.
Moreover, there are no ref T types making it hard to instantiate type parameters with ref structures.
There is 'auto ref' for templated functions.

For heap structs, we have pointers, but it sucks to create aliases all the time to hide the pointer in the name of the pointer struct.

>

It would be nice if the proto object proposal would get implemented. It would cleanse a bit the Object hierarchy and would allow use classes as structs (well still a bit fatter) without extern (c++).

Interesting, did you have a link.

Further, I'm also in favor of adding:

ref struct S
{
   int i;
}

which wouldn't be covered by the proposal?
Https://forum.dlang.org/post/pa1lg6$1lud$1@digitalmars.com -> note this will not make classes equal to structs with reference semantics, it just reorganizes what already exists in Object class giving you more options of what features to use. It won't cover your case probably, that's why I said it still would be a bit fatter in memory footprint.
Really, I would like to make structs and classes more equatable to each other, switching between them sucks.
Well, this will be hard to do probably, because classes have one more feature they implement which is polymorphism, while structs are designed to be plain structures with some behavior.

Anyway, it would be nice to know clearly, what usecases you want to cover by that proposal. The only one I've noticed, is reference semantics, which can be covered by extern c++ final class (not as short as your example, but it works).

May 30, 2021

On Sunday, 30 May 2021 at 12:17:07 UTC, Alexandru Ermicioi wrote:

>

...

Ugh, I think RTF support plays badly with web interface based posts... Please see my comments inlined in your reply.

Also to note, not part of d team, just a wanderer here on forums, and D hobbist.

May 30, 2021

On Sunday, 30 May 2021 at 12:17:07 UTC, Alexandru Ermicioi wrote:

>

Anyway, it would be nice to know clearly, what usecases you want to cover by that proposal.

Simple case: Having a container of ref/ptr structs.

I know ptr structs can already been used with simple pointer types but writing Struct* for every function is tedious, you can alias but doing that with constructor in the mentioned example above is also tedious given the sheer amount of types.
Yes, for ptr types it is solely a stylistic feature to write things shorter.

>

The only one I've noticed, is reference semantics, which can be covered by extern c++ final class (not as short as your example, but it works).

I don't like using extern C++ for that and as it was said, the alignment doesn't seem to fit to structs.
Having value semantics for final classes would also be fine, but it seems that D will stick more on structs as evidenced by the standard library.