Thread overview
Re: Compile-time vs. compile-time
Jan 05
ag0aep6g
January 02
On Tuesday, January 02, 2018 17:51:01 H. S. Teoh via Digitalmars-d wrote:
> object.destroy! :-P

But that doesn't work during compile-time, does it? ;)

- Jonathan M Davis

January 02
On Tue, Jan 02, 2018 at 07:26:54PM -0700, Jonathan M Davis via Digitalmars-d wrote:
> On Tuesday, January 02, 2018 17:51:01 H. S. Teoh via Digitalmars-d wrote:
> > object.destroy! :-P
> 
> But that doesn't work during compile-time, does it? ;)
[...]

Which compile-time? :-D


T

-- 
Computers aren't intelligent; they only think they are.
January 04
On Wed, Jan 03, 2018 at 02:44:21PM +0100, ag0aep6g via Digitalmars-d wrote:
> On 01/03/2018 02:51 AM, H. S. Teoh wrote:
> > 	https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time#But_what_of_runtime_performance.3F
> > 
> > object.destroy! :-P
> 
> In the CTFE section, you explain that it came from constant folding, but you don't point out how the two are different. After reading the section, a newbie might think that the term "CTFE" is for when constant folding evaluates function calls. But that's not what we mean by "CTFE".
> 
> What's missing is that CTFE is forced/guaranteed. It's not an optimization.  When we say "CTFE", we mean the cases where compilation fails if the expression cannot be evaluated.

I wouldn't say that CTFE means that it is forced/guaranteed. But you're right that it could be confusing the way I described it.  I added a section to clarify that usually the compiler would not use CTFE to constant-fold complex expressions, unless the value is required at compile-time.


> I doesn't help that the `i` variables in the examples are (seemingly) globals, but you also talk about putting them in a "busy inner loop". If I just copy the code as it is, `i` is a global and I get actual CTFE. If I put `i` in a loop, it's a local and it's up to the compiler if it does non-CTFE constant folding.

Are you sure that's non-CTFE?  Isn't standard constant folding a part of CTFE?  Anyway, the new section should clear up the confusion.


> Also, you mistyped Stefan Koch's name.

Fixed, thanks!


T

-- 
Try to keep an open mind, but not so open your brain falls out. -- theboz
January 04
On Thursday, January 04, 2018 14:59:44 H. S. Teoh via Digitalmars-d wrote:
> On Wed, Jan 03, 2018 at 02:44:21PM +0100, ag0aep6g via Digitalmars-d
wrote:
> > On 01/03/2018 02:51 AM, H. S. Teoh wrote:
> > >   https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time#Bu
> > >   t_what_of_runtime_performance.3F> >
> > > object.destroy! :-P
> >
> > In the CTFE section, you explain that it came from constant folding, but you don't point out how the two are different. After reading the section, a newbie might think that the term "CTFE" is for when constant folding evaluates function calls. But that's not what we mean by "CTFE".
> >
> > What's missing is that CTFE is forced/guaranteed. It's not an optimization.  When we say "CTFE", we mean the cases where compilation fails if the expression cannot be evaluated.
>
> I wouldn't say that CTFE means that it is forced/guaranteed. But you're right that it could be confusing the way I described it.  I added a section to clarify that usually the compiler would not use CTFE to constant-fold complex expressions, unless the value is required at compile-time.
>
> > I doesn't help that the `i` variables in the examples are (seemingly) globals, but you also talk about putting them in a "busy inner loop". If I just copy the code as it is, `i` is a global and I get actual CTFE. If I put `i` in a loop, it's a local and it's up to the compiler if it does non-CTFE constant folding.
>
> Are you sure that's non-CTFE?  Isn't standard constant folding a part of CTFE?  Anyway, the new section should clear up the confusion.

As I understand it, CTFE and constant folding aren't really related at all. Obviously, a value that was generated as part of CTFE could then take part in constant folding if appropriate, because once the value is generated, it really isn't any different from if that value were written by hand. However, CTFE is never done as a compiler optimization. It's only ever done because a value is required at compile time. So, constant folding won't even trigger CTFE, just like the compiler will never decide that it might be more efficient to call a function at compile time and thus call it at compile time instead of runtime.

- Jonathan M Davis

January 04
On Thu, Jan 04, 2018 at 04:57:25PM -0700, Jonathan M Davis via Digitalmars-d wrote:
> On Thursday, January 04, 2018 14:59:44 H. S. Teoh via Digitalmars-d wrote:
[...]
> > Are you sure that's non-CTFE?  Isn't standard constant folding a part of CTFE?  Anyway, the new section should clear up the confusion.
> 
> As I understand it, CTFE and constant folding aren't really related at all.  Obviously, a value that was generated as part of CTFE could then take part in constant folding if appropriate, because once the value is generated, it really isn't any different from if that value were written by hand. However, CTFE is never done as a compiler optimization. It's only ever done because a value is required at compile time. So, constant folding won't even trigger CTFE, just like the compiler will never decide that it might be more efficient to call a function at compile time and thus call it at compile time instead of runtime.
[...]

Ah, I see. That clears up some misunderstanding on my part. I'll update the article accordingly. Thanks!


T

-- 
Chance favours the prepared mind. -- Louis Pasteur
January 05
On 01/04/2018 11:59 PM, H. S. Teoh wrote:
> I wouldn't say that CTFE means that it is forced/guaranteed. But you're
> right that it could be confusing the way I described it.  I added a
> section to clarify that usually the compiler would not use CTFE to
> constant-fold complex expressions, unless the value is required at
> compile-time.
[...]
> Are you sure that's non-CTFE?  Isn't standard constant folding a part of
> CTFE?
Myself, I use "CTFE" only for the forced kind of compile-time evaluation.

This is my train of thought: CTFE is when `__ctfe` is set. Anything else would be too confusing. During forced compile-time evaluation, `__ctfe` is obviously set. But an optional optimization cannot set `__ctfe`, because that might change the value of the optimized expression. And that's something an optimization must not do.

Example:
----
int foo() { return __ctfe ? 10 : 20; }
int main() { return foo(); }
----

The program must return 20, no matter how aggressively the compiler optimizes.

As far as I can tell, the compilers share this view. For the example, they optimize `main` to `return 20;` [1]. So they evaluate `foo()` during compilation and use `__ctfe = false`.

The spec's wording isn't as clear as it could be, but can be interpreted this way, I think. The relevant statements are [2]:

1) "The __ctfe boolean pseudo-variable [...] evaluates to true at compile time, but false at run time".
2) "In order to be executed at compile time, the function must appear in a context where it must be so executed".

Unfortunately, the first one says "at compile time" which can very well be understood to mean that `__ctfe` should be true during constant folding as done by the optimizer.  But then the second statement would forbid this optional constant folding, because it doesn't allow execution "at compile time" unless the context forces it.

So I'm interpreting "at compile time" to be a synonym for the feature called "CTFE". And then it makes perfect sense (to me):

1) "The __ctfe boolean pseudo-variable [...] evaluates to true [during CTFE], but false [elsewhere]". -- Makes sense.
2) "In order to be executed [via CTFE], the function must appear in a context where [its result must be available during compilation]". -- Meaning that anything else isn't CTFE.


[1] https://godbolt.org/g/6xrDF7
[2] https://dlang.org/spec/function.html#interpretation