digitalmars.D - Non compile time evaluation for initializers
- Steven Schveighoffer (18/18) Oct 25 2007 Is there a good reason why the compiler does not allow non-CTFE initiali...
- Jarrett Billingsley (8/18) Oct 25 2007 I agree. Java and C# allow this, and I think it fits in very nicely wit...
- Janice Caron (10/12) Oct 25 2007 So you're saying that, in general, if
- Bill Baxter (35/52) Oct 26 2007 I think that's only the case for X x being static in the first place.
- Bill Baxter (15/46) Oct 26 2007 Ignore that part.
- Steven Schveighoffer (12/37) Oct 29 2007 Yes, that was my intention. I was not thinking about instance members, ...
- Lutger (4/21) Oct 26 2007 Suppose this is implemented, then how can you achieve constant folding
- Lutger (4/8) Oct 26 2007 Nevermind, I responded too soon and overlooked the proviso that it's
- Max Samukha (5/13) Oct 26 2007 Then if a compile time function is messed up in a way that makes it
- Reiner Pope (9/24) Oct 26 2007 There are plenty of other ways to force compile-time evaluation. I use
- Max Samukha (3/11) Oct 26 2007 Agree
- Lutger (4/19) Oct 26 2007 Hmm yes, it's still an issue. Some functions are quite inefficient for
- Max Samukha (23/42) Oct 26 2007 As Reiner mentioned, the problem is that static variables should not
- Steven Schveighoffer (18/60) Oct 29 2007 I'm not sure that const = CTFE/static = runtime is the right answer. My...
Is there a good reason why the compiler does not allow non-CTFE initializers for non-const variables? For instance, this does not work: Logger log = Log.getLogger("test"); but this does: Logger log; static this() { log = Log.getLogger("test"); } But why is it necessary to prevent the first from compiling to the equivalent of the second? As far as I'm concerned, it's OK if it doesn't evaluate at compile time. And it's much more convenient to write the first version when you are setting up global or static variables instead of using the static this() form. In my mind, CTFE is a form of optimization, one which I can live without if it's not possible, but I still want to be able to compile :) -Steve
Oct 25 2007
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:ffquc2$2kjg$1 digitalmars.com...Is there a good reason why the compiler does not allow non-CTFE initializers for non-const variables? For instance, this does not work: Logger log = Log.getLogger("test"); but this does: Logger log; static this() { log = Log.getLogger("test"); }the existing static constructors. Since you can have multiple static constructors in a module which are just executed in lexical order, a static variable being initialized with a non-compile-time initializer could just be rewritten as a declaration + 1-line static constructor. Basically, your first snippet would be converted into your second.
Oct 25 2007
On 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:Is there a good reason why the compiler does not allow non-CTFE initializers for non-const variables?So you're saying that, in general, if X x = y; won't compile, then the compiler should rewrite it as X x; static this { x = y; } Makes sense to me!
Oct 25 2007
Janice Caron wrote:On 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:I think that's only the case for X x being static in the first place. So static X x = y; is rewritten static X x; static this { x = y; } For class members I guess you might have the non-static initializers turn into some hidden extra work done just before the class's this() constructor. I don't know if it's a good plan or not, but it would certainly be a lot nicer to be able to do: class x { int[] buffer = new int[128]; ... } instead of: class x { int[] buffer; this() { buffer = new int[128]; } this(Arg a) { this(); } this(OtherArg a) { this(); } } I seem to recall that Java allows that. --bbIs there a good reason why the compiler does not allow non-CTFE initializers for non-const variables?So you're saying that, in general, if X x = y; won't compile, then the compiler should rewrite it as X x; static this { x = y; } Makes sense to me!
Oct 26 2007
Bill Baxter wrote:Janice Caron wrote:Ignore that part. I think I was thinking about class X x being a class member. so class Foo { static X x = y; } becomes class Foo { static X x; } static this { Foo.x = y; } --bbOn 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:I think that's only the case for X x being static in the first place. So static X x = y; is rewritten static X x; static this { x = y; }Is there a good reason why the compiler does not allow non-CTFE initializers for non-const variables?So you're saying that, in general, if X x = y; won't compile, then the compiler should rewrite it as X x; static this { x = y; } Makes sense to me!
Oct 26 2007
"Bill Baxter" wroteI think that's only the case for X x being static in the first place.Yes, that was my intention. I was not thinking about instance members, as those could be a significant performance hit if you evaluate the rvalue at runtime every time an instance is created.For class members I guess you might have the non-static initializers turn into some hidden extra work done just before the class's this() constructor. I don't know if it's a good plan or not, but it would certainly be a lot nicer to be able to do: class x { int[] buffer = new int[128]; ... } instead of: class x { int[] buffer; this() { buffer = new int[128]; } this(Arg a) { this(); } this(OtherArg a) { this(); } }Yeah, it does seem like that would be useful. I purposely did not include instance members because I couldn't think of a good example to explain why you would always initialize a variable the same way. Your example not only demonstrates that point, but it is probably a very common one. I think as long as the user is made aware through documentation that the rvalue could be evaluated every time an object is constructed, it would be a good thing to have. -Steve
Oct 29 2007
Janice Caron wrote:On 10/25/07, Steven Schveighoffer <schveiguy yahoo.com> wrote:Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Is there a good reason why the compiler does not allow non-CTFE initializers for non-const variables?So you're saying that, in general, if X x = y; won't compile, then the compiler should rewrite it as X x; static this { x = y; } Makes sense to me!
Oct 26 2007
Lutger wrote:Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 26 2007
On Fri, 26 Oct 2007 10:52:25 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:Lutger wrote:Then if a compile time function is messed up in a way that makes it unevaluatable at compile time, it would be silently used at run-time, which is not desired?Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 26 2007
Max Samukha wrote:On Fri, 26 Oct 2007 10:52:25 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:There are plenty of other ways to force compile-time evaluation. I use const int x = ctfeFunction(); much more than // global namespace int x = ctfeFunction(); I wouldn't have any objection to keeping const meaning ctfe-evaluated, but global non-consts may be postponed till runtime. -- ReinerLutger wrote:Then if a compile time function is messed up in a way that makes it unevaluatable at compile time, it would be silently used at run-time, which is not desired?Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 26 2007
On Fri, 26 Oct 2007 22:47:02 +1000, Reiner Pope <some address.com> wrote:There are plenty of other ways to force compile-time evaluation. I use const int x = ctfeFunction(); much more than // global namespace int x = ctfeFunction(); I wouldn't have any objection to keeping const meaning ctfe-evaluated, but global non-consts may be postponed till runtime. -- ReinerAgree
Oct 26 2007
Max Samukha wrote:On Fri, 26 Oct 2007 10:52:25 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:Hmm yes, it's still an issue. Some functions are quite inefficient for example if they are made to be evaluated at compile time, which doesn't matter in that context but does for the runtime case.Lutger wrote:Then if a compile time function is messed up in a way that makes it unevaluatable at compile time, it would be silently used at run-time, which is not desired?Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 26 2007
On Fri, 26 Oct 2007 15:45:45 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:Max Samukha wrote:As Reiner mentioned, the problem is that static variables should not be initialized at compile-time at all. If you want CTFE put the initializers in const context. int foo() { return 1; } static int x = foo; // module scope, static is optional; foo would be evaluated on module construction class C { static x = foo; // ditto } void bar() { static x = foo; // ditto } Then 'static' keyword here would mean 'global' and compile time constructs would have to be changed to 'const if', 'const assert', etc (Don't beat me please!)On Fri, 26 Oct 2007 10:52:25 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:Hmm yes, it's still an issue. Some functions are quite inefficient for example if they are made to be evaluated at compile time, which doesn't matter in that context but does for the runtime case.Lutger wrote:Then if a compile time function is messed up in a way that makes it unevaluatable at compile time, it would be silently used at run-time, which is not desired?Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 26 2007
"Max Samukha" wroteOn Fri, 26 Oct 2007 15:45:45 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:I'm not sure that const = CTFE/static = runtime is the right answer. My original idea was that the compiler would decide if it could evaluate the rvalue at compile time, and do so if possible, but if not possible, use a static constructor to initialize the variable. The current behavior is to have a compile-time error. I understand your concern that when a CTFE is desired, you will not be able to tell whether the compiler decided to do it or not, but in all cases I can think of: 1. if you don't get CTFE, the evaluation is only a 1 time hit, at the beginning of the program. 2. If the compiler can't do CTFE, then it's probably because the rvalue cannot be evaluated at compile time no matter how you code it. 3. Most of the time, the static constructor form is what you really meant, but the compiler is forcing you to type it out that way. To address this concern, could there be some sort of compile message, like a pragma that tells the compiler it should be able to do CTFE on an rvalue? -SteveMax Samukha wrote:As Reiner mentioned, the problem is that static variables should not be initialized at compile-time at all. If you want CTFE put the initializers in const context. int foo() { return 1; } static int x = foo; // module scope, static is optional; foo would be evaluated on module construction class C { static x = foo; // ditto } void bar() { static x = foo; // ditto } Then 'static' keyword here would mean 'global' and compile time constructs would have to be changed to 'const if', 'const assert', etc (Don't beat me please!)On Fri, 26 Oct 2007 10:52:25 +0200, Lutger <lutger.blijdestijn gmail.com> wrote:Hmm yes, it's still an issue. Some functions are quite inefficient for example if they are made to be evaluated at compile time, which doesn't matter in that context but does for the runtime case.Lutger wrote:Then if a compile time function is messed up in a way that makes it unevaluatable at compile time, it would be silently used at run-time, which is not desired?Janice Caron wrote:...Suppose this is implemented, then how can you achieve constant folding with CTFE in initializers? Since it is not a compile time context anymore, all functions that substitue y will be evaluated at runtime.Nevermind, I responded too soon and overlooked the proviso that it's only rewritten when it doesn't compile, sorry.
Oct 29 2007