Thread overview
Structures and CTFE
Sep 03, 2018
agorkvmh
Sep 03, 2018
bauss
Sep 03, 2018
agorkvmh
Sep 03, 2018
Alex
Sep 03, 2018
agorkvmh
Sep 03, 2018
Stefan Koch
September 03, 2018
Hi all,

Running this:
---
static assert(Foo(1).pos == 2);


struct Foo
{
    this(int i){ advance(); }

    size_t pos =1;

    void advance()
    {
        pragma(msg, pos);
        pos = pos+1;
        pragma(msg, pos);
    }
}

dmd -o- -unittest source/pgs/parser.d
1LU
1LU
---

The static assert passes, but why the second pragma print '1'?

Thanks

September 03, 2018
On Monday, 3 September 2018 at 13:39:25 UTC, agorkvmh wrote:
> Hi all,
>
> Running this:
> ---
> static assert(Foo(1).pos == 2);
>
>
> struct Foo
> {
>     this(int i){ advance(); }
>
>     size_t pos =1;
>
>     void advance()
>     {
>         pragma(msg, pos);
>         pos = pos+1;
>         pragma(msg, pos);
>     }
> }
>
> dmd -o- -unittest source/pgs/parser.d
> 1LU
> 1LU
> ---
>
> The static assert passes, but why the second pragma print '1'?
>
> Thanks

It prints 1, because pragma(msg) is called when the compiler is analyzing the code through the semantic process and not when the body of the function is executed during CTFE.

And since "pos = pos+1" is a runtime construct (technically) then the expression is ignored, unless the function is called during CTFE, but by the time the function is called during CTFE then the pragma(msg) has already been executed.
September 03, 2018
On Monday, 3 September 2018 at 13:52:24 UTC, bauss wrote:
> On Monday, 3 September 2018 at 13:39:25 UTC, agorkvmh wrote:
>> [...]
>
> It prints 1, because pragma(msg) is called when the compiler is analyzing the code through the semantic process and not when the body of the function is executed during CTFE.
>
> And since "pos = pos+1" is a runtime construct (technically) then the expression is ignored, unless the function is called during CTFE, but by the time the function is called during CTFE then the pragma(msg) has already been executed.

Thank you for your quick answer.

There is a way to do print the two values at compile time?
What's the best way to debug a CTFE function?


September 03, 2018
On Monday, 3 September 2018 at 14:00:23 UTC, agorkvmh wrote:
> There is a way to do print the two values at compile time?

Yes. Put a pragma where you static assert for Foo(1).pos equality with 2:

--
static assert(Foo(1).pos == 2);
pragma(msg, Foo(1).pos);

struct Foo
{
    this(int i)
	{
		static assert(this.init.pos == 1);
		advance();
	}

    size_t pos = 1;

    void advance()
    {
        pragma(msg, pos);
        pos = pos + 1;
        pragma(msg, pos);
    }
}

void main(){}
--
> What's the best way to debug a CTFE function?

There is none.

From the Dlang tour:
"CTFE is a mechanism which allows the compiler to execute functions at compile time. There is no special set of the D language necessary to use this feature - whenever a function just depends on compile time known values the D compiler might decide to interpret it during compilation."
https://tour.dlang.org/tour/en/gems/compile-time-function-evaluation-ctfe

As no specifics for CTFE writing exist, no specifics for CTFE testing exist.

So, the way to choose is the one you did: by putting static asserts at the places where you want to assert, that something has to have specific values.
I also added another one, before the initialization of the struct. I.e., before calling the advance function.
September 03, 2018
On Monday, 3 September 2018 at 15:00:33 UTC, Alex wrote:
> On Monday, 3 September 2018 at 14:00:23 UTC, agorkvmh wrote:
>> [...]
>
> Yes. Put a pragma where you static assert for Foo(1).pos equality with 2:
>
> [...]

Thanks, by the way, the autocomplete suggests me '__ctfeWrite', what is it?
September 03, 2018
On Monday, 3 September 2018 at 15:08:57 UTC, agorkvmh wrote:
> On Monday, 3 September 2018 at 15:00:33 UTC, Alex wrote:
>> On Monday, 3 September 2018 at 14:00:23 UTC, agorkvmh wrote:
>>> [...]
>>
>> Yes. Put a pragma where you static assert for Foo(1).pos equality with 2:
>>
>> [...]
>
> Thanks, by the way, the autocomplete suggests me '__ctfeWrite', what is it?

__ctfeWrite was an idea which never got implemented ...
it should be a no-op .... iirc.