Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 12, 2008 CTFE determination? | ||||
---|---|---|---|---|
| ||||
Hi i was messing around in D2 and noticed that the following always is saying that it is only at runtime even when the input is a constant... was wondering if there was a right way to do this. import std.stdio; void main(char[][] args) { writefln("test"); auto ct = test(cast(char[])"123"); auto rt = test(args[0]); writefln(ct); writefln(rt); } pure char[] test(char[] src) { // foo!(src); static if(__traits(compiles,foo!(src)/*check for something only available at compile time...*/)) { return ((cast(char[])"argument available at compiletime of '")~src~cast(char[])"'"); } else { return (cast(char[])"argument available at runtime of '")~src~(cast(char[])"'"); } } pure template foo(char[] src) { const uint foo = src.length; } |
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck wrote:
> Hi i was messing around in D2 and noticed that the following always is saying that it is only at runtime even when the input is a constant... was wondering if there was a right way to do this.
CTFE only kicks in when the function is called in a context which requires a compile-time constant, such as passing the return value from the function as the parameter to a template.
If you don't use the function in that context, then CTFE is *not* active. Thus, your test() function is *not* compile-time evaluated.
The basic reason for this is that if you write a long-running scientific program with fixed inputs you don't want CTFE to kick in just because the inputs are hard-coded.
|
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russell Lewis | well any suggestion on how to determine if a parameter is constant at run time? that is my goal overall... right now it seems casting to invariant ruins anything I can come up with. |
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck:
> well any suggestion on how to determine if a parameter is constant at run time?
How do you plan to use such information once you have it?
Bye,
bearophile
|
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck <bmeck@stedwards.edu> wrote:
> well any suggestion on how to determine if a parameter is constant at run time? that is my goal overall... right now it seems casting to invariant ruins anything I can come up with.
I cannot quite understand what are you trying to achieve here. This is my solution if I got you right:
---
import std.stdio;
void main(string[] args)
{
writefln("test");
static if (__traits(compiles, CompileTime!("123")))
writeln("123 compile");
else
writeln("123 run");
static if (__traits(compiles, CompileTime!(args[0])))
writeln("args[0] compile");
else
writeln("args[0] run");
}
template CompileTime(alias Expr)
{
}
---
|
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | I just get both at run time with your example. I was hoping to encapsulate it somehow so you could just have: import std.stdio; void main(string[] args) { writefln("test"); static if (CompileTimeAvailable!("123")) writeln("123 compile"); else writeln("123 run"); static if (CompileTimeAvailable!(args[0])) writeln("args[0] compile"); else writeln("args[0] run"); } template CompileTimeAvailable(alias expr) { static if(__traits(compiles, CompileTime!(expr))) CompileTimeAvailable = false; else CompileTimeAvailable = false; } template CompileTime(alias Expr) { auto CompileTime = Expr;//Need this to force it to check for CTFE } unfortunately args[0] is not constant so no go... |
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Well if it is available at CTFE I want to hash out as much as possible calculations and store the result, if its not, dont mess with the data and send it to a functions that does the same calculations and stores the result at run time but in a different manner, namely allowing pointers heap etc. IE: if args = ["\w+$"] // gets last word auto reg1 = Regex("\w+$"); // woot got enough to make the struct at Compile time , use structs as needed and hard code that sucker! auto reg2 = Regex(args[0]); // uh oh, dont know at compile time, leave it to a run time call and use pointers and heap as needed! |
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck <bmeck@stedwards.edu> wrote: > I just get both at run time with your example. Again I cannot understand what you are trying to say. Does my example prints wrong results? I'm using DMD 2.019 and get the following: >dmd -run test.d test 123 compile args[0] run so it says that "123" is available at run time, args[0] is not. As expected. > I was hoping to encapsulate it somehow so you could just have: > > import std.stdio; > > void main(string[] args) > { > > writefln("test"); > > static if (CompileTimeAvailable!("123")) > writeln("123 compile"); > else > writeln("123 run"); > > static if (CompileTimeAvailable!(args[0])) > writeln("args[0] compile"); > else > writeln("args[0] run"); > > } > template CompileTimeAvailable(alias expr) > { > static if(__traits(compiles, CompileTime!(expr))) > CompileTimeAvailable = false; > else > CompileTimeAvailable = false; > } > template CompileTime(alias Expr) > { > auto CompileTime = Expr;//Need this to force it to check for CTFE > } > > unfortunately args[0] is not constant so no go... Are you sure you've posted the right example? I can see no attempts at encapsulation. Maybe you wanted > void main(string[] args) > { > writeln("123 at compile time: ", CompileTimeAvailable!("123")); > writeln("args[0] at compile time: ", CompileTimeAvailable!(args[0])); > } |
September 12, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck <bmeck@stedwards.edu> wrote: > Well if it is available at CTFE I want to hash out as much as possible calculations and store the result, if its not, dont mess with the data and send it to a functions that does the same calculations and stores the result at run time but in a different manner, namely allowing pointers heap etc. Got it. This is the best I could come up with to the moment, but it works: --- import std.stdio; void main(string[] args) { mixin CtfeIfPossible!( q{auto r1 =} , q{foo("test")} ); mixin CtfeIfPossible!( q{auto r2 =} , q{foo(args[0])} ); writeln(r1); writeln(r2); } string foo(string s) { return s ~ "-modified"; } template CompileTime(alias Expr) { enum CompileTime = Expr; } template CtfeIfPossible(string Decl, string Expr) { static if (__traits(compiles, CompileTime!(mixin(Expr)))) { pragma(msg, "compile time ", Expr); mixin(Decl ~ "CompileTime!(" ~ Expr ~ ");"); } else { pragma(msg, "runtime ", Expr); mixin(Decl ~ Expr ~ ";"); } } --- It prints: >dmd -run "test.d" compile time foo("test") runtime foo(args[0]) test-modified C:\tmp\test.exe-modified |
September 14, 2008 Re: CTFE determination? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bmeck | bmeck wrote:
> well any suggestion on how to determine if a parameter is constant at run time? that is my goal overall... right now it seems casting to invariant ruins anything I can come up with.
Remember that when a function is not run through CTFE, then it doesn't really know anything about the arguments that it is passed. It could be called several times, sometimes with compile-time-constant args, and sometimes without.
In order to tell the difference, you have to take on the responsibility to specialize the function yourself. One option is to make the function a template, and then pass the compile-time-constant arguments as template parameters:
void myFunc(int CompileTime1, char[] CompileTime2)
(int runtime)
...but that only works if you know that the same args will be compile time args.
|
Copyright © 1999-2021 by the D Language Foundation