Thread overview |
---|
February 21, 2014 immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Attempting to learn CTFE, I tried the following test. size_t counter; uint Test() { if (!__ctfe) { ++counter;// This code is for execution at run time } return 2; } void main() { writeln("counter = ", counter); immutable int n = Test(); int[n] arr; writeln("arrary length = ", arr.length, " ; counter = ", counter); } output: counter = 0 arrary length = 2 ; counter = 1 For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test(). Instead, if I write int[Test()] c; writeln("c.length = ", c.length, " ; counter = ", counter); output is counter = 0 c.length = 2 ; counter = 0 What is wrong in my mind? Thanks, Gopan |
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gopan | On Friday, 21 February 2014 at 13:38:58 UTC, Gopan wrote:
> Attempting to learn CTFE, I tried the following test.
>
> size_t counter;
>
> uint Test()
> {
> if (!__ctfe)
> {
> ++counter;// This code is for execution at run time
> }
> return 2;
> }
>
> void main()
> {
> writeln("counter = ", counter);
>
> immutable int n = Test();
> int[n] arr;
> writeln("arrary length = ", arr.length, " ; counter = ", counter);
> }
>
> output:
> counter = 0
> arrary length = 2 ; counter = 1
>
> For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test().
>
> Instead, if I write
> int[Test()] c;
> writeln("c.length = ", c.length, " ; counter = ", counter);
> output is
> counter = 0
> c.length = 2 ; counter = 0
>
> What is wrong in my mind?
>
> Thanks,
> Gopan
Use enum n = Test() or make immutable n global variable i.e. place it before main.
|
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | Another strange thing: import std.stdio; uint Test() { if (!__ctfe) { return 3; } return 2; } void main() { immutable n = Test(); int[n] arr; writeln("arrary length = ", arr.length, " ; n = ", n); } Output: arrary length = 2 ; n = 3 When you think about it you understand that it's logically right behavior, but it's not acceptable in practice. |
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gopan | On Friday, 21 February 2014 at 13:38:58 UTC, Gopan wrote: > Attempting to learn CTFE, I tried the following test. > > size_t counter; > > uint Test() > { > if (!__ctfe) > { > ++counter;// This code is for execution at run time > } > return 2; > } > > void main() > { > writeln("counter = ", counter); > > immutable int n = Test(); As this is a local variable, this is a runtime initialization, no __ctfe here. Doesn't matter that it's immutable. It's static/global vs local. So, this correctly does ++counter. Make it static immutable n, and counter won't be incremented. > int[n] arr; Not sure if this should compile. n is a run-time value. It just happens that it can be CTFE'd. A more problematic case: --- void main() { immutable n = __ctfe ? 1 : 2; int[n] a; assert(a.length == n); // fails, wat } --- > writeln("arrary length = ", arr.length, " ; counter = ", counter); > } > > output: > counter = 0 > arrary length = 2 ; counter = 1 > > For array declaration to be successful, its size has to be known at compile time. The above code compiles too. But __ctfe seems to be false while performing Test(). > > Instead, if I write > int[Test()] c; > writeln("c.length = ", c.length, " ; counter = ", counter); > output is > counter = 0 > c.length = 2 ; counter = 0 > > What is wrong in my mind? > > Thanks, > Gopan |
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote:
> Another strange thing:
>
> import std.stdio;
>
> uint Test()
> {
> if (!__ctfe)
> {
> return 3;
> }
> return 2;
> }
>
>
>
> void main()
> {
> immutable n = Test();
> int[n] arr;
> writeln("arrary length = ", arr.length, " ; n = ", n);
> }
>
> Output:
> arrary length = 2 ; n = 3
>
> When you think about it you understand that it's logically right behavior, but it's not acceptable in practice.
It looks like 'immutable n = Test();' is executed during both compile time and runtime. Is that what is happening?
|
February 21, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Gopan | On 02/21/2014 08:46 AM, Gopan wrote: > On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote: >> Another strange thing: >> >> import std.stdio; >> >> uint Test() >> { >> if (!__ctfe) >> { >> return 3; >> } >> return 2; >> } >> >> >> >> void main() >> { >> immutable n = Test(); >> int[n] arr; >> writeln("arrary length = ", arr.length, " ; n = ", n); >> } >> >> Output: >> arrary length = 2 ; n = 3 >> >> When you think about it you understand that it's logically right >> behavior, but it's not acceptable in practice. > > It looks like 'immutable n = Test();' is executed during both compile > time and runtime. Is that what is happening? Yes. The compiler needs the value of n at compile time so it evaluates it at compile time. I agree that it is confusing but I feel like it is the responsibility of the programmer to ensure consistent behavior. Ali |
February 23, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 21 February 2014 at 17:04:45 UTC, Ali Çehreli wrote: > On 02/21/2014 08:46 AM, Gopan wrote: > > > On Friday, 21 February 2014 at 14:04:45 UTC, FreeSlave wrote: > >> Another strange thing: > >> > >> import std.stdio; > >> > >> uint Test() > >> { > >> if (!__ctfe) > >> { > >> return 3; > >> } > >> return 2; > >> } > >> > >> > >> > >> void main() > >> { > >> immutable n = Test(); > >> int[n] arr; > >> writeln("arrary length = ", arr.length, " ; n = ", n); > >> } > >> > >> Output: > >> arrary length = 2 ; n = 3 > >> > >> When you think about it you understand that it's logically > right > >> behavior, but it's not acceptable in practice. > > > > It looks like 'immutable n = Test();' is executed during both > compile > > time and runtime. Is that what is happening? > > Yes. The compiler needs the value of n at compile time so it evaluates it at compile time. Thanks for confirming this, Ali. > I agree that it is confusing but I feel like it is the responsibility of the programmer to ensure consistent behavior. > > Ali |
February 23, 2014 Re: immutable int n = Test(); int[n] x;---- compiles, but __ctfe is false. How? | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Friday, 21 February 2014 at 14:14:14 UTC, anonymous wrote:
> Not sure if this should compile. n is a run-time value. It just
> happens that it can be CTFE'd. A more problematic case:
> ---
> void main()
> {
> immutable n = __ctfe ? 1 : 2;
> int[n] a;
> assert(a.length == n); // fails, wat
> }
ie, seeing the declaration 'int[n] a;' one should not assume a.length is same as 'n' at runtime. I would rather prefer getting a compilation error that n is not known at compile time and hence array declaration failed.
If this is eligible for a bugzilla, it is okay. Otherwise, I am very disappointed.
|
Copyright © 1999-2021 by the D Language Foundation