Are these bencmarks recent and real?

Steven Schveighoffer schveiguy at gmail.com
Tue Aug 31 16:32:09 UTC 2021


On 8/31/21 11:44 AM, Ali Çehreli wrote:
> On 8/31/21 8:09 AM, Steven Schveighoffer wrote:
> 
>  > `const ret = 4_000_000.iota.sum;`
>  >
>  > In this case, since this is inside a function, and not assiged to a
>  > global or static variable, it is generated at runtime.
>  >
>  > `pragma(msg, ret);`
>  >
>  > However, here we are requesting the value of `ret` at compile time. The
>  > compiler knows that since it's const, it should have the value it's
>  > initialized with.
> 
> [I change my understanding at the end of this post.]
> 
> But 'const' is not 'static const'. pragma(msg) is being extra helpful by 
> hoping for the availability of the value. (To me, 'const' means "I 
> promise I will not mutate", which has no relation to compile-time 
> availability.)

What `static const` does is require the execution of the expression at 
compile time. Why? Because it needs to put that value into the data 
segment for the linker to use.

The compiler isn't going to do CTFE unless it *has to*. Because CTFE is 
expensive. This is why the cases where CTFE is done are explicit. But 
whether CTFE will work or not depends on whether the code you are 
executing at compile time can be executed at compile time. And that 
isn't decided until the expression is run.

> 
>  > So it runs the *initializer* expression
>  > `4_000_000.iota.sum` at compile-time, and now it has access to the
>  > value. So actually, the CTFE engine runs here instead of at `ret`'s
>  > initialization.
> 
> It makes sense but there are two minor disturbances:
> 
> 1) This is an example of "It went better than I expected".
> 
> 2) Success is determined by trying.
> 
> The following program fails compilation when it gets to 'args.length' 
> after 10 second of compilation:
> 
> import std.range;
> import std.algorithm;
> 
> void main(string[] args) {
>    const ret = 4_000_000.iota.sum + args.length;
>    pragma(msg, ret);
> }
> 

Which actually makes sense :)

CTFE is handed an expression, which is essentially an AST branch that it 
needs to execute. It executes it until it can't, and then gives you the 
error. A CTFE error is like a runtime error, except the "runtime" is 
"compile time".

> Well, nothing is *wrong* here but concepts are muddled. But then I even 
> more TIL that this is the same for templates:
> 
> void foo(int i)() {
> }
> 
> void main() {
>    const i = 42;
>    foo!i();    // Compiles
> }
> 
> You know... Now it feels I knew it all along because CTFE is about 
> expressions, not variables. I need not have a "compile-time variable". 
> Makes sense now. :)

CTFE to me is taking the parsed tree and executing it. But only when it 
needs to. The only odd magic part here is, it can "See through" the 
variable to how it was calculated.

-Steve


More information about the Digitalmars-d mailing list