Jump to page: 1 2
Thread overview
CTFE determination?
Sep 12, 2008
bmeck
Sep 12, 2008
Russell Lewis
Sep 12, 2008
bmeck
Sep 12, 2008
bearophile
Sep 12, 2008
bmeck
Sep 12, 2008
Sergey Gromov
Sep 12, 2008
Sergey Gromov
Sep 12, 2008
bmeck
Sep 12, 2008
Sergey Gromov
Sep 14, 2008
Russell Lewis
Sep 15, 2008
bmeck
Sep 15, 2008
Russell Lewis
Sep 15, 2008
bmeck
September 12, 2008
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
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
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
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
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
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
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
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
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
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.
« First   ‹ Prev
1 2