www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ponce

reply Is this possible at compile time? <c1o2n3t4a5c6t gamesfrommars.fr> writes:
Are these things possible at compile-time?
1 - instancing templated struct/class and using them
2 - calling dynamically linked C functions
3 - accessing files

thanks for answers
Nov 09 2010
next sibling parent Is this possible at compile time? <c1o2n3t4a5c6t gamesfrommars.fr> writes:
Sorry I swapped the topic and user name fields :|
Nov 09 2010
prev sibling next sibling parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Is this possible at compile time? <c1o2n3t4a5c6t gamesfrommars.fr> wrote:

 Are these things possible at compile-time?
 1 - instancing templated struct/class and using them

Structs yes, classes no. And not all kinds.
 2 - calling dynamically linked C functions

No.
 3 - accessing files

Yes. import( "filename" ) gives you the contents as a string. -- Simen
Nov 09 2010
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
ponce:

 Are these things possible at compile-time?
 1 - instancing templated struct/class and using them

Currently classes can't be created at compile time, this fails: class Foo {} int bar() { Foo f = new Foo; return 0; } enum int ignore = bar(); void main() {} But this limit may be eventually removed for some well behaved classes (like classes with pure methods that don't contain other things forbidden in CTFE). Don is more expert on this and he is probably able to give you a better answer. Bye, bearophile
Nov 09 2010
next sibling parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 ponce:
 
 Are these things possible at compile-time?
 1 - instancing templated struct/class and using them

Currently classes can't be created at compile time, this fails: class Foo {} int bar() { Foo f = new Foo; return 0; } enum int ignore = bar(); void main() {} But this limit may be eventually removed for some well behaved classes (like classes with pure methods that don't contain other things forbidden in CTFE). Don is more expert on this and he is probably able to give you a better answer. Bye, bearophile

* no globals (same as pure). * no unsafe features (eg, no asm). * source code must be available. Everything else should work.
Nov 09 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Don:

 Yes. The rules will be:
 * no globals (same as pure).
 * no unsafe features (eg, no asm).
 * source code must be available.
 Everything else should work.

If a class is instantiated at compile-time the memory of its instance goes in the static mutable memory, but then the GC has to manage it differently, because you can't deallocate that memory. Is this a problem? It looks a little like the problems with scoped classes (that are now deprecated by Andrei). (Time ago I have read an interesting paper about a C-like language that supports some kind of classes too. This language is designed for embedded CPUs, so classes may be allocated at compile time only, and never at runtime (where there isn't a dynamic heap), and the compiler takes even care of compacting and squeezing the class instances in the static memory (to reduce as possible the amount of memory they use). Allocating objects at compile time may be a performance optimization for D). Bye, bearophile
Nov 09 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 it would be possible to make it so that any objects allocated with 
 new during CTFE would be in the dynamic heap during runtime.

This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time. Bye, bearophile
Nov 09 2010
next sibling parent reply Don <nospam nospam.com> writes:
bearophile wrote:
 Jonathan M Davis:
 
 it would be possible to make it so that any objects allocated with 
 new during CTFE would be in the dynamic heap during runtime.

This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time. Bye, bearophile

If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.
Nov 09 2010
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Wednesday, November 10, 2010 07:55:42 Steven Schveighoffer wrote:
 On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam nospam.com> wrote:
 bearophile wrote:
 Jonathan M Davis:
 it would be possible to make it so that any objects allocated with new
 during CTFE would be in the dynamic heap during runtime.
 

allocate an object at compile time. Bye, bearophile

If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.

Pardon my ignorance, but how can something evaluated at compile time go on the heap? The heap doesn't exist yet! e.g.: class C { int[] buffer; this() pure { buffer = new int[125];} } C c = new C; How does c go on the heap at compile time? Won't you have to re-run the constructor at runtime to get the right result? Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor?

You likely end up essentially serializing it. You then deserialized it and bring it into the heap when the program loads. It's not a particularly pretty problem, but it should be quite doable. You certainly wouldn't rerun the constructor or whatnot. What you need is to just transfer its saved state onto the heap, translating any pointers and references that it has to whatever they should be in the current heap. - Jonathan M Davis
Nov 10 2010
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 10 Nov 2010 13:08:10 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Wednesday, November 10, 2010 07:55:42 Steven Schveighoffer wrote:

 Pardon my ignorance, but how can something evaluated at compile time go  
 on
 the heap?  The heap doesn't exist yet!

 e.g.:

 class C
 {
    int[] buffer;
    this() pure { buffer = new int[125];}
 }

 C c = new C;

 How does c go on the heap at compile time?  Won't you have to re-run the
 constructor at runtime to get the right result?  Not only that, but even
 if you did run the ctor at compile time, how do you make a copy of c for
 every thread without re-running the ctor?

You likely end up essentially serializing it. You then deserialized it and bring it into the heap when the program loads. It's not a particularly pretty problem, but it should be quite doable. You certainly wouldn't rerun the constructor or whatnot. What you need is to just transfer its saved state onto the heap, translating any pointers and references that it has to whatever they should be in the current heap.

Wow, this seems like a lot of extra effort for zero gain. Is this really the direction we are going? Why can't we just say anything decided at compile time must be immutable or implicitly converted to immutable, and anything else you have to do in a static constructor? -Steve
Nov 10 2010
prev sibling parent Don <nospam nospam.com> writes:
Steven Schveighoffer wrote:
 On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam nospam.com> wrote:
 
 bearophile wrote:
 Jonathan M Davis:

 it would be possible to make it so that any objects allocated with 
 new during CTFE would be in the dynamic heap during runtime.

you allocate an object at compile time. Bye, bearophile

If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.

Pardon my ignorance, but how can something evaluated at compile time go on the heap? The heap doesn't exist yet! e.g.: class C { int[] buffer; this() pure { buffer = new int[125];} } C c = new C; How does c go on the heap at compile time? Won't you have to re-run the constructor at runtime to get the right result? Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor? -Steve

The situation isn't any different to what we already have. You can already do: struct F { int [] w; } F[] foo() { F[] x = new F[6]; foreach(i; 0..x.length) x[i].w = new int[20]; return x; } and foo() can be run at compile time. OTOH, I don't know if there is any case where a CTFE value can actually end up on the heap at runtime. CTFE only kicks in when you need a manifest constant, and AFAIK there's no way to require a class manifest constant -- just an element of one.
Nov 10 2010
prev sibling parent div0 <div0 sourceforge.net> writes:
On 10/11/2010 00:16, Jonathan M Davis wrote:
 On Tuesday, November 09, 2010 13:49:12 bearophile wrote:
 Jonathan M Davis:
 it would be possible to make it so that any objects allocated with
 new during CTFE would be in the dynamic heap during runtime.

This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.

Why not? CTFE stuff should either disappear in the binary, because it's not needed anymore, or it should be the same as if it were created at runtime. CTFE is a great opportunity to create more complicated stuff at cheaper cost (since the calculations are done at compile time instead of runtime), and more importantly, have compile-time constants which are more complex. It's also a great way to generate code. But I don't see why you'd want statically-created objects to be treated differently once the program is running. - Jonathan M Davis

No, that's completely wrong. CTFE should result in constant initialisation values, eg stuff in the .exes read only data segment. CTFE is the same as: immutable string _someString = "hello world!"; Expect that it's: immutable string _someString = reallyComplicatedCTFEfunction(); -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Nov 09 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday 09 November 2010 12:42:06 bearophile wrote:
 Don:
 Yes. The rules will be:
 * no globals (same as pure).
 * no unsafe features (eg, no asm).
 * source code must be available.
 Everything else should work.

If a class is instantiated at compile-time the memory of its instance goes in the static mutable memory, but then the GC has to manage it differently, because you can't deallocate that memory. Is this a problem? It looks a little like the problems with scoped classes (that are now deprecated by Andrei).

Given that it's possible to serialize entire objects to disk in binary form, including all the references that they hold and whatnot in languages like Java, I'm sure that it would be possible to make it so that any objects allocated with new during CTFE would be in the dynamic heap during runtime. - Jonathan M Davis
Nov 09 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 09 Nov 2010 17:14:33 -0500, Don <nospam nospam.com> wrote:

 bearophile wrote:
 Jonathan M Davis:

 it would be possible to make it so that any objects allocated with new  
 during CTFE would be in the dynamic heap during runtime.

allocate an object at compile time. Bye, bearophile

If it's mutable, it'll go on the heap. If it's immutable, it could optionally go into read-only memory (it will be exactly like the .init of a class instance). Classes which are used only during execution of CTFE functions will not be instantiated at runtime.

Pardon my ignorance, but how can something evaluated at compile time go on the heap? The heap doesn't exist yet! e.g.: class C { int[] buffer; this() pure { buffer = new int[125];} } C c = new C; How does c go on the heap at compile time? Won't you have to re-run the constructor at runtime to get the right result? Not only that, but even if you did run the ctor at compile time, how do you make a copy of c for every thread without re-running the ctor? -Steve
Nov 10 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 09 Nov 2010 15:42:06 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Don:

 Yes. The rules will be:
 * no globals (same as pure).
 * no unsafe features (eg, no asm).
 * source code must be available.
 Everything else should work.

If a class is instantiated at compile-time the memory of its instance goes in the static mutable memory, but then the GC has to manage it differently, because you can't deallocate that memory. Is this a problem? It looks a little like the problems with scoped classes (that are now deprecated by Andrei).

The problem with scoped classes are that they are reference types allocated on the stack. This is highly prone to memory problems, especially when classes are usually expected to be in the heap (less care about storing into a global). I'm assuming compile-time classes will be reference types allocated in the data segment. This is more similar to string literals than scope classes. I'm guessing that the resulting class must be immutable, no? Otherwise, how do you allow mutable functions on a class allocated in ROM? FWIW, I like scope classes for optimization (I use them a few places in dcollections), but emplace should be sufficient to replace it. -Steve
Nov 10 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 09, 2010 13:49:12 bearophile wrote:
 Jonathan M Davis:
 it would be possible to make it so that any objects allocated with
 new during CTFE would be in the dynamic heap during runtime.

This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.

Why not? CTFE stuff should either disappear in the binary, because it's not needed anymore, or it should be the same as if it were created at runtime. CTFE is a great opportunity to create more complicated stuff at cheaper cost (since the calculations are done at compile time instead of runtime), and more importantly, have compile-time constants which are more complex. It's also a great way to generate code. But I don't see why you'd want statically-created objects to be treated differently once the program is running. - Jonathan M Davis
Nov 09 2010
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, November 09, 2010 16:24:30 div0 wrote:
 On 10/11/2010 00:16, Jonathan M Davis wrote:
 On Tuesday, November 09, 2010 13:49:12 bearophile wrote:
 Jonathan M Davis:
 it would be possible to make it so that any objects allocated with
 new during CTFE would be in the dynamic heap during runtime.

This is possible, but it doesn't seem what you usually desire when you allocate an object at compile time.

Why not? CTFE stuff should either disappear in the binary, because it's not needed anymore, or it should be the same as if it were created at runtime. CTFE is a great opportunity to create more complicated stuff at cheaper cost (since the calculations are done at compile time instead of runtime), and more importantly, have compile-time constants which are more complex. It's also a great way to generate code. But I don't see why you'd want statically-created objects to be treated differently once the program is running. - Jonathan M Davis

No, that's completely wrong. CTFE should result in constant initialisation values, eg stuff in the .exes read only data segment. CTFE is the same as: immutable string _someString = "hello world!"; Expect that it's: immutable string _someString = reallyComplicatedCTFEfunction();

There are plenty of cases where CTFE is used to create constants, but there are also plenty of places where it can create non-constants - such as setting the initial value for a member variable. Personally, I don't want to have to worry about where in memory an object lives. Constants can - to some extent - be treated as special, but CTFE is _not_ only for generating constants. - Jonathan M Davis
Nov 09 2010