June 27, 2021

On Friday, 25 June 2021 at 21:05:36 UTC, IGotD- wrote:

>

Yes, that's a tradeoff but one I'm willing to take. I'm thinking even bigger managed pointers of perhaps 32 bytes which has more metadata like the allocated size. Managed languages in general have fat pointers which we see everywhere and it is not a big deal.

Which languages use fat pointers? C++ may use it (but is not required to).

>

If you are littering pointers you perhaps should refactor your code, use an array if loads of objects of the same type.

This is what I want to avoid as it makes refcounting more difficult. If D classes are reference types then they should always be referred to through a pointer. If you want to put it in an array, use a struct.

>

Another thing which I'm not that satisfied with D is that there is no built in method of expanding member classes into the host class like C++ which creates pointer littering and memory fragmentation.

Not sure what you mean by expanding? I never liked alias this for structs, inheritance would be simpler. Is this what you mean by expanding?

I think classes in C++ are usually used more like structs in D. C++ programmers tend to avoid using virtuals, so D-style classes (C++ classes with virtual members) tend to be a smaller part of C++ codebases (but it depends on the project, obviously).

June 27, 2021

On Saturday, 26 June 2021 at 20:03:01 UTC, kinke wrote:

>

On Saturday, 26 June 2021 at 13:49:25 UTC, Ola Fosheim Grøstad wrote:

>

Is it possible to inherit from a C++ class and get a D subclass, and is it possible to inherit from a D class and get a C++ class?

Sure thing, with extern(C++) class of course.

That is all good, but it will lead to extern(C++) class replacing D classes. So why not unify right away? Why wait for the inevitable?

>

With C++, you can today, an extern(C++) class C is equivalent to and mangled as C++ C*. You can't pass it directly to some unique_ptr<C> or shared_ptr<T> of course; an according D wrapper reflecting the C++ implementation (library-dependent) would be needed anyway for correct mangling. It'd be implemented as a templated D struct

Yes, this is all good. But if you unify the layout of C++ and D classes and use the same layout as C++ shared_ptr for reference counted D classes then you can easily move back and forth between the languages. I think the presumption that development only happens in D and you only use other people's C++ code is ill advised. One may use a framework in C++ that one also extend in C++, but maybe want to use another language for the high level stuff.

June 27, 2021

On Sunday, 27 June 2021 at 07:54:38 UTC, Ola Fosheim Grøstad wrote:

>

That is all good, but it will lead to extern(C++) class replacing D classes. So why not unify right away? Why wait for the inevitable?

The assumption that all D code and all classes therein are or need to be designed for C++ interop is daring. The DMD frontend uses extern(C++) classes almost exclusively, but that's just for LDC and GDC.

Getting rid of the monitor field was discussed multiple times. The other major and not so trivial difference is that extern(C++) classes have no TypeInfo pointer (in the first vtable slot for extern(D) classes), which also means that dynamic casts don't work, neither in D nor in C++ (for the latter, only for instances instiantiated on the D side). [AFAIK, most C++ implementations put the - of course totally incompatible - C++ TypeInfo into vtable slot -1.]

June 27, 2021

On Sunday, 27 June 2021 at 07:48:22 UTC, Ola Fosheim Grøstad wrote:

>

Which languages use fat pointers? C++ may use it (but is not required to).

Probably about all managed languages. One common method is a that it is actually an identifier it is used in a hash table. Then you can find all sorts of meta data in there. My original point was that this consume more memory in managed languages but nobody seems to mind.

>

Not sure what you mean by expanding? I never liked alias this for structs, inheritance would be simpler. Is this what you mean by expanding?

When you use a struct as a member variable in another struct the data will be expanded into the host struct. If the member struct is 16 bytes then the host struct will have grow 16 bytes to accommodate that member struct.

This is not the case in D with classes as classes always are allocated on the heap using dynamic allocation. This leads to more fragmentation and memory consumption.

June 27, 2021

On Sunday, 27 June 2021 at 08:41:27 UTC, kinke wrote:

>

Getting rid of the monitor field was discussed multiple times.

You don't have to get rid of it, just implicitly declare it for classes that use monitors? I don't think it has to be at a specific offset?

>

The other major and not so trivial difference is that extern(C++) classes have no TypeInfo pointer (in the first vtable slot for extern(D) classes), which also means that dynamic casts don't work, neither in D nor in C++ (for the latter, only for instances instiantiated on the D side). [AFAIK, most C++ implementations put the - of course totally incompatible - C++ TypeInfo into vtable slot -1.]

But D could just extend C++ typeinfo?

June 27, 2021

On Sunday, 27 June 2021 at 09:35:10 UTC, IGotD- wrote:

>

Probably about all managed languages.

I am sceptical of this assumption. There are no reasons for a GC language to require the usage of fat pointers?

>

When you use a struct as a member variable in another struct the data will be expanded into the host struct. If the member struct is 16 bytes then the host struct will have grow 16 bytes to accommodate that member struct.

This is not the case in D with classes as classes always are allocated on the heap using dynamic allocation. This leads to more fragmentation and memory consumption.

Ok, I understand what you mean, but classes tend to be used for "big objects". I don't think there is anything that prevents a private class reference to be replaced by an inline representation as an optimization if no references ever leak. If you use whole program optimizations such things could also be done for public members.

What is holdning D back here is the lack of a high level IR after the frontend where such global passes could improve the implementation quality.

So, this is at the core of good language design; keep the model simple, but enable and allow optimizations. Too much special casing and you end up with a language that is difficult to extend and a neverending discovery of corner cases and compiler bugs.

June 27, 2021

On Sunday, 27 June 2021 at 09:46:45 UTC, Ola Fosheim Grøstad wrote:

>

On Sunday, 27 June 2021 at 08:41:27 UTC, kinke wrote:

>

Getting rid of the monitor field was discussed multiple times.

You don't have to get rid of it, just implicitly declare it for classes that use monitors? I don't think it has to be at a specific offset?

It's not about classes using monitors themselves, it's about people potentially using synchronized (obj) for some arbitrary class reference obj. Embedding it in the instance directly prevents having to use a hashtable or similar. But I'm certainly not fond of that field as it's a rare use case.

> >

The other major and not so trivial difference is that extern(C++) classes have no TypeInfo pointer (in the first vtable slot for extern(D) classes), which also means that dynamic casts don't work, neither in D nor in C++ (for the latter, only for instances instiantiated on the D side). [AFAIK, most C++ implementations put the - of course totally incompatible - C++ TypeInfo into vtable slot -1.]

But D could just extend C++ typeinfo?

Sure, 'just' :D - as it 'just' takes someone to implement it (for all supported C++ runtimes). It's always the same problem, lots of talk and blabla in the forum, but hardly any real action coming out of it.

June 27, 2021

On Sunday, 27 June 2021 at 10:11:44 UTC, kinke wrote:

>

It's not about classes using monitors themselves, it's about people potentially using synchronized (obj) for some arbitrary class reference obj.

I wasn't aware this was a thing. If people want this they can just embed a mutex in the class themselves. No point in having it everywhere. You usually don't want to coordinate over one instance anyway.

>

Sure, 'just' :D - as it 'just' takes someone to implement it (for all supported C++ runtimes). It's always the same problem,

Right, but what does all supported C++ runtimes mean? I thought LDC was tied to clang, which I guess means two runtimes? If C++ doesn't use arbitrary negative offsets, then D could use those?

June 27, 2021

On Sunday, 27 June 2021 at 10:11:44 UTC, kinke wrote:

>

On Sunday, 27 June 2021 at 09:46:45 UTC, Ola Fosheim Grøstad

We need organized action,Instead of doing it blindly.

I always say organize.

June 27, 2021

On Sunday, 27 June 2021 at 12:00:41 UTC, Ola Fosheim Grøstad wrote:

>

On Sunday, 27 June 2021 at 10:11:44 UTC, kinke wrote:
Right, but what does all supported C++ runtimes mean? I thought LDC was tied to clang, which I guess means two runtimes? If C++ doesn't use arbitrary negative offsets, then D could use those?

LDC isn't tied to clang at all, we just use the same backend. - It's libstdc++ and libc++ in the POSIX world (most likely including MinGW), and MSVC++ for 'native' Windows. Another difficulty is that TypeInfo_Class instances are generated by the compiler, and not in the frontend either, meaning that DMD, GDC and LDC would all need to be adapted.