Re: Class instance memory overhead lower than 3 words?
On Wednesday, January 24, 2018 17:50:35 Ali Çehreli via Digitalmars-d-learn wrote: > On 01/24/2018 05:43 PM, Jonathan M Davis wrote: > > On Thursday, January 25, 2018 00:10:32 Nicholas Wilson via > > Digitalmars-d- > > > > learn wrote: > >> One pointer for the vtbl, one for the monitor, not sure what the > >> other one is. > > > > The TypeInfo maybe? I'm not sure where that lives. > > > > - Jonathan M Davis > > Nested classes have that third pointer: > > > class A { > } > static assert(__traits(classInstanceSize, A) == 2 * (void*).sizeof); > > void main() { > class B { > } > static assert(__traits(classInstanceSize, B) == 3 * (void*).sizeof); > } > > Are there other cases? Well, a class nested inside another class would, but that's just another type of nested class. If it's not nested, it won't have a pointer to any kind of outer scope though. - Jonathan M Davis
Re: Class instance memory overhead lower than 3 words?
On 01/24/2018 05:43 PM, Jonathan M Davis wrote: On Thursday, January 25, 2018 00:10:32 Nicholas Wilson via Digitalmars-d- learn wrote: One pointer for the vtbl, one for the monitor, not sure what the other one is. The TypeInfo maybe? I'm not sure where that lives. - Jonathan M Davis Nested classes have that third pointer: class A { } static assert(__traits(classInstanceSize, A) == 2 * (void*).sizeof); void main() { class B { } static assert(__traits(classInstanceSize, B) == 3 * (void*).sizeof); } Are there other cases? Ali
Re: Class instance memory overhead lower than 3 words?
On Thursday, January 25, 2018 00:10:32 Nicholas Wilson via Digitalmars-d- learn wrote: > One pointer for the vtbl, one for the monitor, not sure what the > other one is. The TypeInfo maybe? I'm not sure where that lives. - Jonathan M Davis
Re: Class instance memory overhead lower than 3 words?
On Wednesday, 24 January 2018 at 22:27:40 UTC, Nordlöw wrote: On Wednesday, 24 January 2018 at 21:47:26 UTC, H. S. Teoh wrote: On Wed, Jan 24, 2018 at 09:48:21PM +, Nordlöw via Digitalmars-d-learn wrote: Why is the memory overhead for a class instance as high as 3 words (24 bytes on 64-bit systems? I find that annoyingly much for my knowledge database application. [...] There's been an attempt to get rid of the Monitor field, which takes up one word, but it didn't seem to have gone anywhere the last time it was discussed. I believe originally it was always initialized, but lately it seems to have been changed to be lazily initialized, so at least you'll only incur the computational cost if you actually use it. Nevertheless, the field itself is still there. T Can I use `*(cast(size_t*)__monitor)` for storing my own stuff in a class instance `c` if I never use monitors? :) Maybe, the runtime when destroying that class might think the monitor is set and try and destroy the mutex it thinks is where the pointer points to. BTW: the documentation on the concept of monitors is kind of sparse here https://dlang.org/spec/class.html#class_properties What is the `__monitor` property used for? Something with synchronized member functions? It is used for ``` MyClass mc; synchronized(mc) // <- { ... } ``` and I believe synchronized member functions and member functions of `synchronized class` (which are the same thing really). The __monitor field points to a mutex object which is managed by the runtime.
Re: Class instance memory overhead lower than 3 words?
On Wednesday, 24 January 2018 at 21:48:21 UTC, Nordlöw wrote: Why is the memory overhead for a class instance as high as 3 words (24 bytes on 64-bit systems? I find that annoyingly much for my knowledge database application. I'm aware of extern(C++), having one word overhead, but such extern(C++)-classes cannot use all of D; I get compilation errors such as node.d(99,25): Error: Internal Compiler Error: type `inout(Edge)[]` can not be mapped to C++ One pointer for the vtbl, one for the monitor, not sure what the other one is. C++ classes have one pointer for the vtbl at offset of -1 size_t.sizeof Declaring that particular method as extern(D) will fix that problem.
Re: Class instance memory overhead lower than 3 words?
On Wednesday, 24 January 2018 at 21:47:26 UTC, H. S. Teoh wrote: On Wed, Jan 24, 2018 at 09:48:21PM +, Nordlöw via Digitalmars-d-learn wrote: Why is the memory overhead for a class instance as high as 3 words (24 bytes on 64-bit systems? I find that annoyingly much for my knowledge database application. [...] There's been an attempt to get rid of the Monitor field, which takes up one word, but it didn't seem to have gone anywhere the last time it was discussed. I believe originally it was always initialized, but lately it seems to have been changed to be lazily initialized, so at least you'll only incur the computational cost if you actually use it. Nevertheless, the field itself is still there. T Can I use `*(cast(size_t*)__monitor)` for storing my own stuff in a class instance `c` if I never use monitors? :) BTW: the documentation on the concept of monitors is kind of sparse here https://dlang.org/spec/class.html#class_properties What is the `__monitor` property used for? Something with synchronized member functions?
Re: Class instance memory overhead lower than 3 words?
On Wed, Jan 24, 2018 at 09:48:21PM +, Nordlöw via Digitalmars-d-learn wrote: > Why is the memory overhead for a class instance as high as 3 words (24 > bytes on 64-bit systems? I find that annoyingly much for my knowledge > database application. [...] There's been an attempt to get rid of the Monitor field, which takes up one word, but it didn't seem to have gone anywhere the last time it was discussed. I believe originally it was always initialized, but lately it seems to have been changed to be lazily initialized, so at least you'll only incur the computational cost if you actually use it. Nevertheless, the field itself is still there. T -- What is Matter, what is Mind? Never Mind, it doesn't Matter.
Class instance memory overhead lower than 3 words?
Why is the memory overhead for a class instance as high as 3 words (24 bytes on 64-bit systems? I find that annoyingly much for my knowledge database application. I'm aware of extern(C++), having one word overhead, but such extern(C++)-classes cannot use all of D; I get compilation errors such as node.d(99,25): Error: Internal Compiler Error: type `inout(Edge)[]` can not be mapped to C++
Re: [dlang library documentation] Why there are dlang.org/library and dlang.org/phobos?
On Tuesday, 23 January 2018 at 19:05:21 UTC, Seb wrote: On Monday, 22 January 2018 at 19:38:45 UTC, John Gabriele wrote: On Monday, 22 January 2018 at 15:32:29 UTC, Adam D. Ruppe wrote: On Monday, 22 January 2018 at 15:18:38 UTC, Johann wrote: Maybe it's due to historical reasons. It's actually "future" reasons... the /phobos is the original one, and /library was supposed to replace it, but now many years later, /library is still kinda neglected and they both just exist. What's needed to remove the "/phobos" one? Is it a decision from on-high, or is there a lot of editing of hardcoded links required? This discussion and the referenced news group thread should give insights: https://github.com/dlang/dlang.org/pull/1526 Thank you!
Re: getting member functions of a struct and Error: identifier expected following ., not this
On Wednesday, 24 January 2018 at 07:55:01 UTC, thedeemon wrote: On Tuesday, 23 January 2018 at 00:00:38 UTC, aliak wrote: [...] The struct defined inside a scope can mention variables defined in that scope (e.g. use them in its methods), so it needs a pointer to the place where those closed variables live. That's the main difference between such struct and a static one that cannot use those scope vars. I guess you're seeing that pointer as additional member. As for static foreach, when you write a simple foreach over some compile-time tuple (like in this case), it's unrolled at compile time similarly to "static foreach", the main difference is whether it creates a sub-scope for the loop body or not. "foreach" creates one, "static foreach" doesn't. Ah makes sense. Thanks!
Re: `Alias this` to a mixed in property
On Wednesday, 24 January 2018 at 14:21:42 UTC, ag0aep6g wrote: The spec says that you cannot make an overload set just by mixing in multiple functions/methods with the same name. Instead, you have to do it like this: mixin getter g; mixin setter!int s; alias p = g.p; alias p = s.p; https://dlang.org/spec/template-mixin.html#mixin_scope Thanks a lot! I didn't know you could do overloads by way of multiple aliases with the same name. I meant to use this for mixing in multiple instantiations generated from a static foreach over an AliasSeq of types, but generating unique identifiers poses an extra challenge. I may go for string mixin's instead, which I just discovered do work: ``` import std.stdio; enum getter = ` @property int p() { writeln(__LINE__, " mixin getter"); return 3; } `; string setter(string T) pure { return ` @property int p(` ~ T ~ ` arg) { writeln(__LINE__, " mixin setter ` ~ T ~ `" , arg); return 4; } `; } struct S { mixin(getter); mixin(setter("int")); alias p this; } void main(string[] args) { S s; s = 7; int i = s; } ```
Re: `Alias this` to a mixed in property
On 01/24/2018 02:24 PM, Bastiaan Veelo wrote: `Alias this` to mixed in properties does not seem to work, see below. If you think it should, I'll file an issue. Otherwise: can this be made to work somehow? Not supposed to work as it is. The spec says that you cannot make an overload set just by mixing in multiple functions/methods with the same name. Instead, you have to do it like this: mixin getter g; mixin setter!int s; alias p = g.p; alias p = s.p; https://dlang.org/spec/template-mixin.html#mixin_scope
`Alias this` to a mixed in property
Hi, `Alias this` to mixed in properties does not seem to work, see below. If you think it should, I'll file an issue. Otherwise: can this be made to work somehow? Interestingly, if you uncomment either the mixin getter or setter (row 36 or 37) and its corresponding use in `main`, then the remaining property works. Does the compiler detect identical names and then does some additional mangling which messes with my `alias this` maybe? ``` import std.stdio; // version = manual; // Manually written property works, obviously. mixin template getter() { @property int p() { writeln(__LINE__, " mixin getter"); return 3; } } mixin template setter(T) { @property int p(T arg) { writeln(__LINE__, " mixin setter ", typeid(T), ' ', arg); return 4; } } struct S { version (manual) { @property int p() { writeln(__LINE__, " manual getter"); return 3; } @property int p(int arg) { writeln(__LINE__, " manual setter int ", arg); return 4; } } else { mixin getter;// row 36 mixin setter!int;// row 37 } alias p this; } void main(string[] args) { S s; s = 7; int i = s; } ``` Error: cannot implicitly convert expression s of type S to int.