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