Confusion/trying to understand CTFE keywords

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Jun 7 04:58:40 UTC 2018


On Thursday, June 07, 2018 04:41:35 Gopan via Digitalmars-d-learn wrote:
> On Tuesday, 5 June 2018 at 22:08:32 UTC, Stefan Koch wrote:
> > On Tuesday, 5 June 2018 at 18:00:05 UTC, Steven Schveighoffer
> >
> > wrote:
> >> No, it's definitely a bug. main is not being evaluated at
> >> compile time. The real result of this function should be a
> >> compile-time error -- __ctfe is a *runtime* value that is
> >> always defined based on whether you are __ctfe or not.
> >> Therefore, n must be a runtime value, and not usable as a
> >> static array dimension.
> >>
> >> If the posted code is valid, then this should be valid as well:
> >>
> >> static if(__ctfe)
> >>
> >>    immutable n = 1;
> >>
> >> else
> >>
> >>    immutable n = 2;
> >>
> >> But it's not.
> >>
> >> -Steve
> >
> > I see what you mean.
> > I fear fixing this bug will not be easy without breaking
> > arguably valid uses.
>
> Will it be feasible something like
>
> int n = CTFE(foo(3)); //dont limit CTFE to enum or immutable,
> etc.  You are calling explicitly.
> int[n] arr;
>
> So that, we can be explicit about when CTFE kicks in.  In that
> case, don't assign value to n at runtime as it has been
> initialized at compile time.  This way, we can get rid of the
> intermediate enums which are introduced just for the sake of
> inviting CTFE.  Also, this way, it will not silently break
> existing code; instead a compilation error must be thrown "value
> of n not known at compile time" for the below code.
>
> immutable n = foo();
> int[n] arr;
>
> Unless called throgh CTFE(....), dont go for CTFE.
>
> Will this work?
>
> Just putting my thoughts... I am no expert.

The core problem with this is that it's using a runtime variable at compile
time, which doesn't normally work. The fact that it works with an immutable
variable is a weird quirk based on the fact that it was assumed that the
value would be identical at both runtime and compile time, and as already
shown in this thread, that results in other bugs.

It would be trivial enough to create a wrapper template so that you can do
something like

immutable n = ctfe!(foo());

e.g.

template ctfe(alias value)
{
    enum ctfe = value;
}

The problem is the fact that a runtime variable is being allowed in a
context that requires a compile time value. That violates how CTFE normally
works, increasing the confusion about when CTFE kicks in, and as shown in
this thread, it can result in subtle bugs.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list