June 14, 2015
On Sunday, 14 June 2015 at 09:46:56 UTC, JDemler wrote:
> On Sunday, 14 June 2015 at 05:52:00 UTC, ketmar wrote:
>> oh, seems that i managed to make everything even less understandable...
>
> Your code works perfectly and makes at least some sense to me. Thank you.
>
> If i understand it correctly: __traits-time = templateinstatiation-time = pragma-time before ctfe-time?

Not really. These things are just (conceptually) done as/when they are required. If a template instantiation needs to do ctfe to calculate it's result, it does it. If some code running in ctfe needs the result of a template, it instantiates it.

The only distinction you have to think about is compile-time vs run-time, with the caveat that ctfe code is run as if it were run-time, but the result can be used at compile-time. If you imagine ctfe as being "compiling the function, running it, getting the answer and copying it in to your code" then even that distinction goes away and you just have ct vs rt.
June 14, 2015
On Sun, 14 Jun 2015 09:46:54 +0000, JDemler wrote:

> On Sunday, 14 June 2015 at 05:52:00 UTC, ketmar wrote:
>> oh, seems that i managed to make everything even less understandable...
> 
> Your code works perfectly and makes at least some sense to me. Thank you.
> 
> If i understand it correctly: __traits-time = templateinstatiation-time = pragma-time before ctfe-time?

not quite right. there is no dedicated "CTFE time". compiler triggers CTFE when it needs to, i.e. when it sees something like this:

  enum myval = myfunction(); // or mytemplate!(...)

i.e. when it need a value in compile time. the interpreter is invoked, it evaluates (interprets) the given code (function or template instantiation), and then it returns result (or raises an error).

so CTFE can occur at any stage of semantic analysis.

to be clear: compiler goes (roughly) thru this stages:

1. parsing and building AST.

2. semantic analysis.

3. generating code.

at the stage (1) only syntax is checked, and source is converted to internal representation (AST).

at the state (2) compiler tries to actually make sense of your code. it deducing types, checking type correctness and such. if it need to instantiate some template, it does that here. it does semantic for each function (note: not for templates or eponymous templates!), one by one.

and here compiler may step on something that needs CTFE. it invokes interpreter on this stage. so there is no dedicated "CTFE time", compiler does it while it busy with semantic analysis, on demand. this way it avoids evaluating CTFE values that never used, which is good for compile speed. ;-)

pragmas and traits are executed by the very same CTFE engine, on demand too. i.e. when compiler hits pragma or traits during semantic analysis, compiler executes that.

overal semantic stage is more complex, of course, but i hope you get the idea.

June 14, 2015
On Sunday, 14 June 2015 at 10:04:35 UTC, John Colvin wrote:
> On Sunday, 14 June 2015 at 09:46:56 UTC, JDemler wrote:
>> On Sunday, 14 June 2015 at 05:52:00 UTC, ketmar wrote:
>>> oh, seems that i managed to make everything even less understandable...
>>
>> Your code works perfectly and makes at least some sense to me. Thank you.
>>
>> If i understand it correctly: __traits-time = templateinstatiation-time = pragma-time before ctfe-time?
>
> Not really. These things are just (conceptually) done as/when they are required. If a template instantiation needs to do ctfe to calculate it's result, it does it. If some code running in ctfe needs the result of a template, it instantiates it.
>
> The only distinction you have to think about is compile-time vs run-time, with the caveat that ctfe code is run as if it were run-time, but the result can be used at compile-time. If you imagine ctfe as being "compiling the function, running it, getting the answer and copying it in to your code" then even that distinction goes away and you just have ct vs rt.

If that is the case then i really do not get why my first example compiles and my second does not.

The compiler sees the pragma(msg, test(e)) and runs test(e).
If test uses __traits it does not work if it does not it works.

If __traits is just another ctfe function i dont see the difference.
June 14, 2015
On Sunday, 14 June 2015 at 10:10:51 UTC, ketmar wrote:
> i.e. when it need a value in compile time. the interpreter is invoked, it evaluates (interprets) the given code (function or template instantiation), and then it returns result (or raises an error).

One important thing I didn't see stated clearly by anyone in here:

CTFE may run at compile time but it follows the same rules as run time evaluation (plus some restrictions).

This means, you can't use dynamic values (e.g. function parameters) in static contexts (e.g. __traits).

Example:
----
int f(int x)
{
    if (__ctfe)
    {
        enum e = x; /* nope, not even during CTFE */
        alias t = some_template!x; /* nope */
        pragma(msg, x); /* nope */
    }
	return x;
}

enum result = f(1); /* CTFE-ing f */
----

June 14, 2015
On Sunday, 14 June 2015 at 10:29:09 UTC, anonymous wrote:
> On Sunday, 14 June 2015 at 10:10:51 UTC, ketmar wrote:
>> i.e. when it need a value in compile time. the interpreter is invoked, it evaluates (interprets) the given code (function or template instantiation), and then it returns result (or raises an error).
>
> One important thing I didn't see stated clearly by anyone in here:
>
> CTFE may run at compile time but it follows the same rules as run time evaluation (plus some restrictions).
>
> This means, you can't use dynamic values (e.g. function parameters) in static contexts (e.g. __traits).
>
> Example:
> ----
> int f(int x)
> {
>     if (__ctfe)
>     {
>         enum e = x; /* nope, not even during CTFE */
>         alias t = some_template!x; /* nope */
>         pragma(msg, x); /* nope */
>     }
> 	return x;
> }
>
> enum result = f(1); /* CTFE-ing f */
> ----

So if i want to use parameters in a static context at compile time i have to pass them as template parameters?

That would explain my problems. Thanks
June 14, 2015
On Sunday, 14 June 2015 at 10:41:24 UTC, JDemler wrote:
> So if i want to use parameters in a static context at compile time i have to pass them as template parameters?

Yes, template parameters are fine.


June 14, 2015
On Sun, 14 Jun 2015 10:29:08 +0000, anonymous wrote:

> One important thing I didn't see stated clearly by anyone in here:
> 
> CTFE may run at compile time but it follows the same rules as run time evaluation (plus some restrictions).
> 
> This means, you can't use dynamic values (e.g. function parameters) in
> static contexts (e.g. __traits).

yes, i managed to write a wall of text escaping to talk about the main issue of the thread. ;-)

June 14, 2015
On Sunday, 14 June 2015 at 10:16:24 UTC, JDemler wrote:
> On Sunday, 14 June 2015 at 10:04:35 UTC, John Colvin wrote:
>> [...]
>
> If that is the case then i really do not get why my first example compiles and my second does not.
>
> The compiler sees the pragma(msg, test(e)) and runs test(e).
> If test uses __traits it does not work if it does not it works.
>
> If __traits is just another ctfe function i dont see the difference.

An easy to remember rule: If it won't work at runtime, it won't work in ctfe.
1 2
Next ›   Last »