CTFE and Static If Question
H. S. Teoh
hsteoh at quickfur.ath.cx
Thu May 7 15:29:01 UTC 2020
On Thu, May 07, 2020 at 03:00:18PM +0000, jmh530 via Digitalmars-d-learn wrote:
> I am curious how ctfe and static ifs interact.
Then you should find this article helpful:
https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
> In particular, if an enum bool passed as a template parameter or
> run-time one will turn an if statement into something like a static if
> statement (perhaps after the compiler optimizes other code away). In
> the code below, I am a function that takes a bool as a template
> parameter and another that has it as a run-time parameter. In the
> first, I just pass an compile-time bool (y0) into it. In the second I
> have run-time (x0) and compile-time (y0).
There are multiple things here that should not be confused:
1) Template instantiation (includes static if): a template takes some
number of compile-time arguments, and emits multiple copies of the
template definition, with said arguments substituted for its
parameters. Templates are processed early on in the compilation
process, and can change the structure of the AST that the compiler
sees.
2) CTFE: runs code that has already been compiled into a form that's
ready to be emitted as runtime code, and feeds the return value back
to the compiler so that it can be used as a compile-time value
somewhere else. Note that CTFE can only run code that has *passed*
the template instantiation stage (even though the resulting value
*can* be used for instantiation of other templates, but it cannot
change the CTFE'd code itself).
3) Code optimization: this takes place independently of (1) and (2), and
happens as part of code generation. It basically tries to transform
the machine code so that it runs more efficiently at runtime. It may
simplify statements or eliminate redundant / dead code, but this has
nothing to do with templates, static if, or CTFE; it's a
transformation applied toward the end of the compilation process and
it's universally applied to all runtime code (unless you disable
optimizations).
> Does foo!y0(rt) generate the same code as foo(rt, y0)?
It generates a different AST structure. But at the end, the optimizer
may reduce them into the same code, depending on the circumstances.
> How is the code generated by foo(rt, x0) different from foo(rt,y0)?
There is no difference, except that in the latter case, the optimizer
may realize that the argument is a compile-time constant, and inline the
function with its return value instead of emitting a runtime call. This
has nothing to do with templates or CTFE, it's purely an optimizer issue
(and different optimizers may do things differently -- it does not
change the meaning of the code).
> auto foo(bool rtct)(int rt) {
> static if (rtct)
> return rt + 1;
> else
> return rt;
> }
>
> auto foo(int rt, bool rtct) {
> if (rtct == true)
> return rt + 1;
> else
> return rt;
> }
>
> void main() {
> int rt = 3;
> bool x0 = true;
> bool x1 = false;
> assert(foo(rt, x0) == 4);
> assert(foo(rt, x1) == 3);
>
> enum y0 = true;
> enum y1 = false;
> assert(foo!y0(rt) == 4);
> assert(foo!y1(rt) == 3);
> assert(foo(rt, y0) == 4);
> assert(foo(rt, y1) == 3);
> }
[...]
T
--
IBM = I Blame Microsoft
More information about the Digitalmars-d-learn
mailing list