www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Structures and CTFE

reply agorkvmh <forengj gmail.com> writes:
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
Sep 03 2018
parent reply bauss <jj_1337 live.dk> writes:
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.
Sep 03 2018
parent reply agorkvmh <forengj gmail.com> writes:
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?
Sep 03 2018
parent reply Alex <sascha.orlov gmail.com> writes:
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.
Sep 03 2018
parent reply agorkvmh <forengj gmail.com> writes:
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?
Sep 03 2018
parent Stefan Koch <uplink.coder googlemail.com> writes:
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.
Sep 03 2018