www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Questions about initialization of array of objects

reply "Andrey" <andr-sar yandex.ru> writes:
I'm not sure about proper understanding of RAII idiom, but should 
objects in array be automatically constructed during array 
initialization?

Example.

class ClassPoint {
     int x,y;
}

struct StructPoint {
     int x,y;
}

ClassPoint[8] arr; //static array of null references;
StructPoint[8] arr2;

arr[0].x=1 //error, there is no object
arr2[0].x=1 //OK.

Here I have two questions:

1) Can you have automatically constructed objects with default 
class constructor?
2) Can you setup memory attributes for static array using 
core.memory functions, say, to force GC not to scan this portion 
of memory during collection?
Jan 12 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 12 January 2013 at 19:07:38 UTC, Andrey wrote:
 I'm not sure about proper understanding of RAII idiom, but 
 should objects in array be automatically constructed during 
 array initialization?
Members of static arrays are initialized to their default values.
 Example.

 class ClassPoint {
     int x,y;
 }
This is initialized to null.
 struct StructPoint {
     int x,y;
 }
This is initialized to StructPoint(0,0).
 ClassPoint[8] arr; //static array of null references;
 StructPoint[8] arr2;

 arr[0].x=1 //error, there is no object
 arr2[0].x=1 //OK.

 Here I have two questions:

 1) Can you have automatically constructed objects with default 
 class constructor?
No. It is possible to create a wrapper struct type with "alias this" to ClassPoint[8], which defaults to preallocated objects, but as a drawback each instance of such type would default to same class references and this makes the hack mostly unusable.
 2) Can you setup memory attributes for static array using 
 core.memory functions, say, to force GC not to scan this 
 portion of memory during collection?
I do not understand what you mean here.
Jan 12 2013
next sibling parent reply "Andrey" <andr-sar yandex.ru> writes:
 2) Can you setup memory attributes for static array using 
 core.memory functions, say, to force GC not to scan this 
 portion of memory during collection?
I do not understand what you mean here.
I mean static uint setAttr(in void* p, uint a) from core.memory and enum BlkAttr.NO_SCAN; Can I use here cast(void*)arr.ptr and what effect it will cause on array of class objects?
Jan 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrey:

 Can I use here cast(void*)arr.ptr and what effect it will cause 
 on array of class objects?
If that array is allocated on the heap them mabye the GC will ignore those class instances. Bye, bearophile
Jan 12 2013
parent reply "Andrey" <andr-sar yandex.ru> writes:
 If that array is allocated on the heap them mabye the GC will 
 ignore those class instances.
I think GC scans stack for pointers. At least, official manual says this: The garbage collector looks for roots in: 1) the static data segment 2) the stacks and register contents of each thread 3) the TLS (thread-local storage) areas of each thread 4) any roots added by core.memory.GC.addRoot() or core.memory.GC.addRange() If the only pointer to an object is held outside of these areas, then the collector will miss it and free the memory.
Jan 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrey:

 I think GC scans stack for pointers.
Right. And I think you can't stop the GC from scanning the stack.
 The garbage collector looks for roots in:
 ...
What I meant to say is that if you put the fixed sized array on the heap then maybe you can mark it as noscan. Maybe if you tell us more generally what you are trying to do, we can answer something useful :-) Bye, bearophile
Jan 12 2013
parent "Andrey" <andr-sar yandex.ru> writes:
 Maybe if you tell us more generally what you are trying to do, 
 we can answer something useful :-)
:-) I'm trying to explore the possibilities of memory management in D for fine tuning of real long time running applications. Such technique as object pools, which are more friendly to CPU cache. I know that you can use std.conv.emplace stuff, but I'm trying to stay within GC. I use unrolled linked lists, which consist of connected fixed array chunks, allocated on the GC heap. Anyway, thanks everyone for answers.
Jan 12 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
I don't know the answers to those difficult questions. So I offer 
only partial tentative comments.

Maxim Fomin answering Andrey:

 ClassPoint[8] arr; //static array of null references;
I prefer to call them fixed sized arrays, because the "static" word is too much overloaded in D.
 StructPoint[8] arr2;

 arr[0].x=1 //error, there is no object
 arr2[0].x=1 //OK.

 Here I have two questions:

 1) Can you have automatically constructed objects with default 
 class constructor?
No. It is possible to create a wrapper struct type with "alias this" to ClassPoint[8], which defaults to preallocated objects, but as a drawback each instance of such type would default to same class references and this makes the hack mostly unusable.
If ClassPoint has just a default constructor and the original poster wants to allocate those class instances in place, then maybe it's possible to invent something like this, that creates initialized class instances, but I think it's not very useful: Emplace!(ClassPoint)[8] arr;
 2) Can you setup memory attributes for static array using 
 core.memory functions, say, to force GC not to scan this 
 portion of memory during collection?
I do not understand what you mean here.
I think currently you can't tell the GC to ignore part of the stack. Fixed sized arrays are sometimes on the stack. So maybe it's not possible. Bye, bearophile
Jan 12 2013
parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 12 January 2013 at 20:18:59 UTC, bearophile wrote:
 Maxim Fomin answering Andrey:

 ClassPoint[8] arr; //static array of null references;
I prefer to call them fixed sized arrays, because the "static" word is too much overloaded in D.
I see, but these names are interchangeable. Dlang.org uses "static" (as opposed to dynamic) and tdpl tends to use fixed-size name.
 Bye,
 bearophile
Jan 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Maxim Fomin:

 I see, but these names are interchangeable. Dlang.org uses 
 "static" (as opposed to dynamic) and tdpl tends to use 
 fixed-size name.
If you call a1 static array, then what name do you give to a2? A static static array? void main() { int[5] a1; static int[5] a2; __gshared int[5] a3; } Bye, bearophile
Jan 12 2013
next sibling parent reply "Andrey" <andr-sar yandex.ru> writes:
 A static static array?
Very static array? =)
Jan 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrey:

 A static static array?
Very static array? =)
Elsewhere I have suggested a "static static", because I think sometimes D static is not static enough: http://d.puremagic.com/issues/show_bug.cgi?id=9088 So with that you have Very static static arrays too :o) Bye, bearophile
Jan 12 2013
parent reply "Andrey" <andr-sar yandex.ru> writes:
 Elsewhere I have suggested a "static static", because I think 
 sometimes D static is not static enough:

 http://d.puremagic.com/issues/show_bug.cgi?id=9088

 So with that you have Very static static arrays too :o)
I think such words as "single" and "only" are more appropriate in your case. single static function(); Or, if the developers will finally allow to take advantages of the unicode: static², static³... :-)
Jan 12 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Andrey:

 I think such words as "single" and "only" are more appropriate 
 in your case.

 single static function();
Right, but we generally try to minimize the number of keywords. "static static" is a special case of a more general feature, templated(), that is similar to the "utilizes" keyword discussed here, in Figure 21: "Minimizing Dependencies within Generic Classes for Faster and Smaller Programs" by Dan Tsafrir, Robert W. Wisniewski, David F. Bacon and Bjarne Stroustrup: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.155.1773 The "static static" is the same as an empty templated(): int foo(T)() if (is(T == char) || is(T == dchar) || is(T == wchar)) { templated() dchar[] table = ['a', 'b', 'c']; templated() immutable val = someHeavyCTFE(10); // uses table and val here return 0; } Adapted from that Figure 21: struct C(X, Y, Z) { void f1() templated(X, Z) { // only allowed to use X or Z, not Y } void f2() { // for backward compatibility, this is // equivalent to: void f2() templated(X,Y,Z) } class Inner templated(Y) { // only allowed to use Y, not X nor Z } } templated() (or utilizes()) is much more flexible than "static static". And I generally I'd like templated() to be implemented instead of "static static".
 Or, if the developers will finally allow to take advantages of 
 the unicode: static², static³... :-)
Please, no :-) Bye, bearophile
Jan 12 2013
next sibling parent "Andrey" <andr-sar yandex.ru> writes:
I think this might be a problem because every template instance 
creates separate independent class, as far as I know.

Well, maybe you can use function pointer and create static 
constructor. More job need to be done, but the resulting class 
doesn't lose much and even become more flexible, configurable;

final class StaticMyClass {

	static void _myfun() {
		writeln("Hello!");
	}
}

class MyClass(T) {
	uint x, y;

	static void function() myfun;

	static this() {
		MyClass.myfun = &StaticMyClass._myfun;
	}

         //still you have additional memory consumed by static 
constructor function;

	this() {
		this.myfun();
	}
}

void main() {
     auto obj = new MyClass!int();
}
Jan 12 2013
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
 The "static static" is the same as an empty  templated():


 int foo(T)() if (is(T == char) || is(T == dchar) || is(T == 
 wchar)) {
      templated() dchar[] table = ['a', 'b', 'c'];
      templated() immutable val = someHeavyCTFE(10);
     // uses table and val here
     return 0;
 }
Sorry "static static" is the same as " templated() static". Bye, bearophile
Jan 12 2013
parent "Andrey" <andr-sar yandex.ru> writes:
Could be even simpler. But I do not know about additional 
overhead. How do you feel on this?

abstract class _MyClass {

     static string str = "Hello!";

     static void myfun() {
	writeln(str);
     }

}

class MyClass(T) : _MyClass {

	this() {
             this.myfun();
	}
}

P.S.: sorry if I don't understand your vision about this problem 
correctly. I've never been doing template programming much.
Jan 12 2013
prev sibling parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Saturday, 12 January 2013 at 21:12:06 UTC, bearophile wrote:
 Maxim Fomin:

 I see, but these names are interchangeable. Dlang.org uses 
 "static" (as opposed to dynamic) and tdpl tends to use 
 fixed-size name.
If you call a1 static array, then what name do you give to a2? A static static array? void main() { int[5] a1; static int[5] a2; __gshared int[5] a3; } Bye, bearophile
Static static array (yes, it is rather dumb). I see no point in selecting more appropriate name among these too if both are correct, both are heavily used in discussions (judging by google search on dlang.org and subdomains - even if I query fixed array, I still receive pages with static name), both are understandable (the only little confusion happens with arrays with static attribute) and there is no language standard which uses some set of terminology. A case when popular naming is incorrect, is, for example, calling this(this) a struct copy constructor (it happens sometimes) - when it is certainly incorrect, because it is a postblit, and copy constructor is another thing. Even such strictly speaking incorrect naming is understandable and widely used.
Jan 12 2013