www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Structs as reference types?

reply sighoya <sighoya gmail.com> writes:
What about:

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

instead of:

```D
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
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Saturday, 29 May 2021 at 18:34:44 UTC, sighoya wrote:
 What about:

 ```D
 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
next sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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 29
prev sibling parent reply tsbockman <thomas.bockman gmail.com> writes:
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:

 ```D
 ptr struct S
 {
      int i;
 }
 // ...
 ```
That is literally a final class: ```D 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`: ```D 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 29
next sibling parent evilrat <evilrat666 gmail.com> writes:
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:

 ```D
 ptr struct S
 {
      int i;
 }
 // ...
 ```
That is literally a final class: ```D 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`: ```D 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. ```d 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 29
prev sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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
parent reply sighoya <sighoya gmail.com> writes:
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: ```D 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
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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: ```D 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
next sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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
prev sibling parent sighoya <sighoya gmail.com> writes:
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.
May 30